Пропавшие без вести дополняющий для алгоритма RSA

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

Описание

Отсутствие дополняющий для алгоритма 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++
Значение по умолчанию: 'off'
Синтаксис командной строки: CRYPTO_RSA_NO_PADDING
Влияние: носитель
ID CWE: 310, 326, 327, 780

Введенный в R2018a