2015-12-08 3 views
0

У меня проблема с шифрованием с помощью RSA_public_encrypt.Проблема с OpenSSL с RSA_public_encrypt

Что я имею: модуль (1024 бит), показатель (каждый раз, когда они не меняются) и открытый текст.

Что я хочу: шифровать простой текст, используя открытый ключ, состоящий из модуля и экспонента (которые передаются как HEX-строка) с RSA_PKCS1_OAEP_PADDING.

Проблема заключается в том, что функция RSA_public_encrypt вызывает нарушение доступа, и я не понимаю, почему. Я видел множество подобных примеров в Интернете, но они, похоже, из-за комментариев.

Вот мой код:

procedure RSAPublicEncrypt(const PlainText, Modulus, Exponent: AnsiString); 
    var 
    PublicKey: pRSA; 
    Output: Integer; 
    BN_Modulus, BN_Exponent: pBIGNUM; 
    Res: AnsiString; 
    begin 
    Result := ''; 
    try 
     PublicKey := RSA_new(); //Creating new key 

     PublicKey^.n := BN_new; //Creating new modulus 
     Output := BN_hex2bn(PublicKey^.n, PAnsiChar(Modulus)); //Convert modulut from hex to BIGNUM 

     PublicKey^.e := BN_new; //same to the exponent 
     BN_hex2bn(PublicKey^.e, PAnsiChar(Exponent)); 

     //Trying to encrypt. Here I get the AV 
     Output := RSA_public_encrypt(Length(PlainText), PAnsiChar(PlainText), PAnsiChar(Res), PublicKey, RSA_PKCS1_OAEP_PADDING); 
    finally 
     BN_clear_free(PublicKey^.e); 
     BN_clear_free(PublicKey^.n); 
     RSA_free(PublicKey); 
    end; 
    end; 

Что я делаю неправильно? Помоги мне, пожалуйста. Заранее спасибо!

ответ

0

Наконец-то я нашел источник проблемы. Это была неправильная реализация структуры RSA. Не хватало одного указателя:

RSA = record 
    pad: integer; 
    version: integer; 
    meth: pRSA_METHOD; 
    engine: pointer; //<-- this one was missing 
    n: pBIGNUM; 
    e: pBIGNUM; 
    d: pBIGNUM; 
    p: pBIGNUM; 
    q: pBIGNUM; 
    dmp1: pBIGNUM; 
    dmq1: pBIGNUM; 
    iqmp: pBIGNUM; 
    ex_data: CRYPTO_EX_DATA; 
    references: integer; 
    flags: integer; 
    _method_mod_n: pBN_MONT_CTX; 
    _method_mod_p: pBN_MONT_CTX; 
    _method_mod_q: pBN_MONT_CTX; 
    bignum_data: ^byte; 
    blinding: ^BN_BLINDING; 
end; 
0

Res не инициализирован, но вы пишете на него. Я предполагаю, что опечатка и что линия

Result := ''; 

действительно должен быть

Res := ''; 

Если это так, то там не хватает места, чтобы провести свой результат, и вы должны использовать что-то вроде SetLength для Res в сделайте его достаточно большим, чтобы сохранить результат плюс нулевой ограничитель.

SetLength(Res, Length(PlainText) + 1); // or whatever is appropriate 

Вы должны знать, что AnsiString является подсчет ссылок и автоматически управляется как обычная строка, но PAnsiChar нет, и считается предопределенные строки, которая не изменяет его размер (память, выделенная) автоматически. Когда вы передаете AnsiString в PAnsiChar, внутри компилятор передает указатель на первый символ AnsiString, минуя его поля отсчета ссылок и длины. Он не меняет Res в массив AnsiChar. Поэтому его следует использовать с большой осторожностью.

Другим способом было бы определить Res как массив AnsiChar

Res : Array[0..255] of AnsiChar; 

, например, который явно показывает память, выделенную, но установка длины является более гибким.

Смежные вопросы