exponenta event banner

Отсутствует заполнение для алгоритма RSA

Контекст, используемый в операции шифрования или подписи, не связан ни с одним дополнением

Описание

Этот дефект возникает при выполнении шифрования или подписи RSA с помощью объекта контекста без связывания объекта со схемой заполнения.

Например, шифрование выполняется с помощью объекта контекста, который изначально не был связан с определенным дополнением.

ret = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING);
...
ret = EVP_PKEY_encrypt(ctx, out, &out_len, in, in_len)

Риск

Схемы заполнения удаляют детерминизм из алгоритма RSA и защищают операции RSA от определенных видов атак. Заполнение гарантирует, что данное сообщение не приведет к одному и тому же шифротексту при каждом его шифровании. Без заполнения злоумышленник может запускать атаки с выбранным открытым текстом против криптосистемы.

Зафиксировать

Перед выполнением операции RSA свяжите объект контекста со схемой заполнения, совместимой с операцией.

  • Шифрование: Используйте схему заполнения OAEP.

    Например, используйте EVP_PKEY_CTX_set_rsa_padding функция с аргументом RSA_PKCS1_OAEP_PADDING или RSA_padding_add_PKCS1_OAEP функция.

    ret = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING);
    
    Также можно использовать схемы PKCS # 1v1.5 или SSLv23. Имейте в виду, что эти схемы считаются небезопасными.

    Затем можно использовать такие функции, как EVP_PKEY_encrypt / EVP_PKEY_decrypt или RSA_public_encrypt / RSA_private_decrypt по контексту.

  • Подпись: Используйте схему заполнения RSA-PSS.

    Например, используйте EVP_PKEY_CTX_set_rsa_padding функция с аргументом RSA_PKCS1_PSS_PADDING.

    ret = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PSS_PADDING);
    Также можно использовать схемы ANSI X9.31, PKCS # 1v1.5 или SSLv23. Имейте в виду, что эти схемы считаются небезопасными.

    Затем можно использовать такие функции, как EVP_PKEY_sign-EVP_PKEY_verify пара или RSA_private_encrypt-RSA_public_decrypt пара в контексте.

При выполнении двух видов операций с одним и тем же контекстом после первой операции сбросьте схему заполнения в контексте перед второй операцией.

Примеры

развернуть все

#include <stddef.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf;
size_t out_len;


int func(unsigned char *src, size_t len){
  EVP_PKEY_CTX *ctx;
  EVP_PKEY* pkey;

  /* Key generation */
  ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA,NULL); 
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_keygen_init(ctx);
  if (ret <= 0) fatal_error();
  ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048);
  if (ret <= 0) fatal_error();
  ret = EVP_PKEY_keygen(ctx, &pkey);  
  if (ret <= 0) fatal_error();

  /* Encryption */
  EVP_PKEY_CTX_free(ctx);
  ctx = EVP_PKEY_CTX_new(pkey,NULL); 
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_encrypt_init(ctx);
  if (ret <= 0) fatal_error();
  return EVP_PKEY_encrypt(ctx, out_buf, &out_len, src, len); 
}

В этом примере перед шифрованием с помощью EVP_PKEY_encrypt, конкретное заполнение не связано с объектом контекста ctx.

Исправление - задание заполнения в контексте перед шифрованием

Одной из возможных корректировок является установка схемы заполнения OAEP в контексте.

#include <stddef.h>
#include <openssl/rsa.h>
#include <openssl/evp.h>

#define fatal_error() exit(-1)

int ret;
unsigned char *out_buf;
size_t out_len;


int func(unsigned char *src, size_t len){
  EVP_PKEY_CTX *ctx;
  EVP_PKEY* pkey;

  /* Key generation */
  ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA,NULL); 
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_keygen_init(ctx);
  if (ret <= 0) fatal_error();
  ret = EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048);
  if (ret <= 0) fatal_error();
  ret = EVP_PKEY_keygen(ctx, &pkey);  
  if (ret <= 0) fatal_error();

  /* Encryption */
  EVP_PKEY_CTX_free(ctx);
  ctx = EVP_PKEY_CTX_new(pkey,NULL); 
  if (ctx == NULL) fatal_error();

  ret = EVP_PKEY_encrypt_init(ctx);
  ret = EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING); 
  if (ret <= 0) fatal_error();
  if (ret <= 0) fatal_error();
  return EVP_PKEY_encrypt(ctx, out_buf, &out_len, src, len); 
}

Информация о результатах

Группа: Криптография
Язык: C | C++
По умолчанию: Откл.
Синтаксис командной строки: CRYPTO_RSA_NO_PADDING
Воздействие: среднее
CWE ID: 310, 326, 327, 780
Представлен в R2018a