先看代码
void MyRSA_Test(RSA *rsa, bool bUsePublicEncrypt, int padding)
{
unsigned char plain[512] = "Hello world!";
unsigned char cipper[512] = { 0 };
unsigned char newplain[512] = { 0 };
int outl = 0xffffffff;
if (bUsePublicEncrypt)
{
outl = RSA_public_encrypt(strlen((char*)plain), plain, cipper, rsa, padding);
}
else
{
outl = RSA_private_encrypt(strlen((char*)plain), plain, cipper, rsa, padding);
}
if (outl == 0xffffffff)
{
printf("\nERROR\n");
return;
}
printf("\n密文开始\n");
for (int i = 0; i < outl; i++)
{
printf("%02x ", cipper[i]);
if ((i + 1) % 10 == 0) printf("\n");
}
printf("\n密文结束\n");
int outl2 = 0xffffffff;
if (bUsePublicEncrypt)
{
outl2 = RSA_private_decrypt(outl, cipper, newplain, rsa, padding);
}
else
{
outl2 = RSA_public_decrypt(outl, cipper, newplain, rsa, padding);
}
if (outl2 == 0xffffffff)
{
printf("\nERROR\n");
return;
}
printf("\n---------解密------\n%s\n", newplain);
for (int i = 0; i < outl2; i++)
{
printf("%02x ", newplain[i]);
}
printf("\n");
#if 0
{
if (0)
{
BIO* _bio = BIO_new(BIO_s_mem());
PEM_write_bio_RSAPublicKey(_bio, rsa);
RSA* x = NULL;
PEM_read_bio_RSAPublicKey(_bio, &x, NULL, NULL);
outl = RSA_public_encrypt(strlen((char*)plain), plain, cipper, x, RSA_PKCS1_OAEP_PADDING);
}
// 上面代码作用一样,但是RSA 公钥加密每次结果是不一样的。不能直接作为对比
outl = RSA_public_encrypt(strlen((char*)plain), plain, cipper, rsa, RSA_PKCS1_PADDING);
}
#endif
}
int Test()
{
RSA *rsa = RSA_new();
int ret = 0;
BIGNUM *bne = BN_new();
ret = BN_set_word(bne, RSA_F4);
ret = RSA_generate_key_ex(rsa, 512, bne, NULL);
MyRSA_Test(rsa, true, RSA_PKCS1_PADDING);
MyRSA_Test(rsa, true, RSA_PKCS1_PADDING);
MyRSA_Test(rsa, true, RSA_SSLV23_PADDING);
MyRSA_Test(rsa, true, RSA_SSLV23_PADDING);
// 无法加密
MyRSA_Test(rsa, true, RSA_NO_PADDING);
MyRSA_Test(rsa, true, RSA_NO_PADDING);
MyRSA_Test(rsa, true, RSA_PKCS1_OAEP_PADDING);
MyRSA_Test(rsa, true, RSA_PKCS1_OAEP_PADDING);
// 无法加密
MyRSA_Test(rsa, true, RSA_PKCS1_PSS_PADDING);
MyRSA_Test(rsa, true, RSA_PKCS1_PSS_PADDING);
// 无法加密
MyRSA_Test(rsa, true, RSA_PKCS1_PADDING_SIZE);
MyRSA_Test(rsa, true, RSA_PKCS1_PADDING_SIZE);
///
MyRSA_Test(rsa, false, RSA_PKCS1_PADDING);
MyRSA_Test(rsa, false, RSA_PKCS1_PADDING);
// 无法加密
MyRSA_Test(rsa, false, RSA_SSLV23_PADDING);
MyRSA_Test(rsa, false, RSA_SSLV23_PADDING);
// 无法加密
MyRSA_Test(rsa, false, RSA_NO_PADDING);
MyRSA_Test(rsa, false, RSA_NO_PADDING);
// 无法加密
MyRSA_Test(rsa, false, RSA_PKCS1_OAEP_PADDING);
MyRSA_Test(rsa, false, RSA_PKCS1_OAEP_PADDING);
// 无法加密
MyRSA_Test(rsa, false, RSA_PKCS1_PSS_PADDING);
MyRSA_Test(rsa, false, RSA_PKCS1_PSS_PADDING);
// 无法加密
MyRSA_Test(rsa, false, RSA_PKCS1_PADDING_SIZE);
MyRSA_Test(rsa, false, RSA_PKCS1_PADDING_SIZE);
return 0;
}
文中已经根据结果增加了注释,我们知道可以用公钥加密、私钥解密。或者用私钥加密、公钥解密。因此定义了函数 MyRSA_Test ,可以灵活设置用公钥还是私钥加密。
测试结果已经用注释说明了。
通过测试可以确认:
RSA 公钥加密,连续运行多次(比如2次)结果是不一样的,这不影响解密。
RSA 私钥加密,连续运行多次结果是一样的。
RSA 公钥加密私钥解密可以使用的 padding 参数如下:
RSA_PKCS1_PADDING
RSA_SSLV23_PADDING
RSA_PKCS1_OAEP_PADDING
RSA 私钥加密公钥解密只能使用的 padding 参数:
RSA_PKCS1_PADDING
同时,用 #if 0 限制的代码里面,屏蔽了一部分代码。 RSA 是一对密钥包含公钥私钥。可以提取出公钥(或者私钥)单独使用。