RSA_public_encrypt

时间:2015-12-08 13:31:01

标签: delphi openssl rsa

我遇到了使用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;

我做错了什么?请帮帮我。提前谢谢!

2 个答案:

答案 0 :(得分:0)

Res未初始化,但您正在写入它。我假设一个错字和那行

Result := '';

真的应该

Res := '';

如果是这样,那么没有足够的空间来保存你的结果,你需要使用类似SetLength到Res的东西来使它足够大以保持结果加上一个空终止符。

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

您需要注意AnsiString是引用计数并自动控制,就像普通字符串一样,但PAnsiChar不是,并且被认为是一个预定义的字符串,它不会自动改变其大小(分配的内存)。当您将AnsiString强制转换为PAnsiChar时,编译器会在内部传递指向AnsiString的第一个char的指针,绕过其引用计数和长度字段。它不会将Res更改为AnsiChar数组。因此必须非常谨慎地使用它。

另一种方法是将Res定义为AnsiChar的数组

Res : Array[0..255] of AnsiChar;
例如,

明确显示已分配的内存,但设置长度更灵活。

答案 1 :(得分: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;