OpenSSL RSA_public_encrypt奇怪的行为 [英] OpenSSL RSA_public_encrypt strange behavior

查看:189
本文介绍了OpenSSL RSA_public_encrypt奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I’m trying to write a simple encryption routine in C using OpenSSL and I’ve found something strange. I’m not a C guru nor OpenSSL professional. So I might have made a mistake.

该功能如下

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

我在相同的数据上多次调用该函数,每次生成不同的值它被称为。它显然是错误,因为指数模数对于创建的 RSA结构是常量,并且每个输入数据相同呼叫。

I call that function on same data several times and it generates different value each time it is called. It is apparently wrong because exponent and modulus for created RSA structure are constant and input data is the same in each call.

那么为什么 RSA_public_encrypt 表现那样?

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

How should I generate a public key for RSA encryption based on exponent and modulus?

我犯了错误?

推荐答案

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

This is actually correct, and you're not making a mistake. Your confusion stems from the RSA_PKCS1_OAEP_PADDING parameter to RSA_public_encrypt.

RSA加密过程实际上是:

The RSA encryption process is actually:


  1. 采用明文(普通)和编码,生成encoded_plain。

  2. 加密encoded_plain。

  1. Take the plaintext (plain) and encode it , producing encoded_plain.
  2. Encrypt encoded_plain.

(正如您所料,解密过程需要您同时使用解密该值,然后解码消息)。

(As you would expect, the decryption process requires you to both decrypt the value, and then decode the message).

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

The RSA_PKCS1_OAEP_PADDING parameter specifies how the plaintext should be encoded (that OAEP encoding should be used).

简化说明是OAEP填充使用一些随机值作为填充,因此 xxxxxxxABC yyyyyyyABC zzzzzzzABC 都是明文的有效encoded_plain值,而encode_plain加密到不同的值。如果你执行相应的解密(并通过将相同的 RSA_PKCS1_OAEP_PADDING 参数传递给 RSA_private_decrypt )进行解码,你仍然应该得到ABC作为每个密文的输出,因为填充剥离了所有三个。

A simplified explanation is that OAEP padding uses some random values for the padding, so both xxxxxxxABC and yyyyyyyABC and zzzzzzzABC are all valid encoded_plain values for your plaintext, and those encoded_plain encrypts to a different value. If you perform the corresponding decrypt (and decode, by passing the same RSA_PKCS1_OAEP_PADDING paramater to RSA_private_decrypt) operation, you should still get "ABC" as an output for each of the ciphertexts, as the padding stripped off all three.

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

(If you want to be precise, the OAEP encoding scheme is more complicated that, see RFC 3447 section 7.1.1. But those are probably details you don't care about.)

这篇关于OpenSSL RSA_public_encrypt奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆