OpenSSL RSA_public_encrypt奇怪的行为

我想用C编写一个简单的encryption程序,我发现了一些奇怪的东西。 我不是C大师,也不是OpenSSL专业人员。 所以我可能犯了一个错误。

function如下

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"))); } 

我在相同的数据上多次调用该函数,每次调用它时都会生成不同的值。 这显然是错误的,因为创build的RSA结构的 指数模数是恒定的,input数据在每个调用中是相同的。

那么为什么RSA_public_encrypt行为呢?

我应该如何生成基于指数模数的 RSAencryption公钥?

在哪里我犯了错误?

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

RSAencryption过程实际上是:

  1. 取明文(普通)并编码 ,产生encoded_plain。
  2. encryptionencoded_plain。

(正如你所期望的,解密过程要求你解密这个值,然后解码这个消息)。

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

一个简单的解释是,OAEP填充使用一些随机值进行填充,因此xxxxxxxABCyyyyyyyABCzzzzzzzABC都是明文的有效encoded_plain值,而这些encoded_plainencryption为不同的值。 如果您执行相应的解密操作(并通过将相同的RSA_PKCS1_OAEP_PADDINGparameter passing给RSA_private_decrypt )来进行RSA_private_decrypt ,那么您应该仍然将“ABC”作为每个密文的输出,因为填充将全部三个都删除。

(如果你想精确的话,OAEP编码scheme更为复杂,参见RFC 3447第7.1.1节,但这些可能是你不关心的细节)。

编码范围在rsa_encrypt函数的末尾结束。 你的返回指针将指向一个无效的内存区域,可能不会包含你期望的内容,因为别人(例如另一个线程)写了它。 解释填充的答案是正确的。