OpenSSL RSA_public_encrypt奇怪的行为

ano*_*nim 0 openssl ios

我正在尝试使用OpenSSL在C中编写一个简单的加密例程,我发现了一些奇怪的东西.我不是C大师,也不是OpenSSL专业人士.所以我可能犯了一个错误.

功能如下

char *rsa_encrypt(char *data)
{
    const char xponent_in_hex[] = "010001";
    const char modulus_in_hex[] = "D0BA16F11907E7B0819705A15264AC29BEE9F1EC5F22642992
    D3E27100B7F212864A624A12FFB6D531712B0B0225AAD0C2E313D077A7DB2A5A33483EEFF41A9D";    

    BIGNUM *xponent = NULL;
    BIGNUM *modulus = NULL;

    BN_hex2bn(&xponent, xponent_in_hex);
    BN_hex2bn(&modulus, modulus_in_hex);

    RSA *rsa = RSA_new();
    rsa->e = xponent;
    rsa->n = modulus;
    rsa->iqmp = NULL;
    rsa->d = NULL;
    rsa->p = NULL;
    rsa->q = NULL;

    char encoded[512] = { 0 };
    RSA_public_encrypt(
    strlen(data), 
    (const unsigned char *)data, 
    (unsigned char *)encoded,
    rsa, 
    RSA_PKCS1_OAEP_PADDING
);

    RSA_free(rsa);

    return (encoded);
}

int _tmain(int argc, _TCHAR* argv[])
{
    printf("%s\n", base64_encode(rsa_encrypt("ABC")));
    printf("%s\n", base64_encode(rsa_encrypt("ABC")));
    printf("%s\n", base64_encode(rsa_encrypt("ABC")));
}
Run Code Online (Sandbox Code Playgroud)

我在相同的数据上多次调用该函数,并且每次调用它时都会生成不同的值.这显然是错误的,因为创建的RSA结构的指数模数是常数,并且输入数据在每次调用中是相同的.

那么为什么RSA_public_encrypt表现那样呢?

如何基于指数模数生成RSA加密的公钥?

我犯了错误的地方?

Jum*_*ram 5

这实际上是正确的,你没有犯错误.你的困惑源于RSA_PKCS1_OAEP_PADDING参数RSA_public_encrypt.

RSA加密过程实际上是:

  1. 取明文(普通)并对其进行编码,生成encoded_plain.
  2. 加密encoded_plain.

(正如您所料,解密过程要求您解密该值,然后解码该消息).

RSA_PKCS1_OAEP_PADDING参数指定明文应如何编码(应使用OAEP编码).

一个简化的解释是,OAEP填充使用一些随机值填充,这样既xxxxxxxABCyyyyyyyABCzzzzzzzABC都是有效的encoded_plain值的明文,而那些encoded_plain加密为不同的值.如果你执行相应的解密(并通过传递相同的RSA_PKCS1_OAEP_PADDING参数解码RSA_private_decrypt)操作,你应该仍然得到"ABC"作为每个密文的输出,因为填充剥离了所有三个.

(如果您想要精确,OAEP编码方案更复杂,请参阅RFC 3447第7.1.1节.但这些可能是您不关心的细节.)