900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 使用OpenSSL1.1.1中的libcrypto库进行RSA加密与解密数据

使用OpenSSL1.1.1中的libcrypto库进行RSA加密与解密数据

时间:2021-04-02 06:52:02

相关推荐

使用OpenSSL1.1.1中的libcrypto库进行RSA加密与解密数据

废话不多说, 直接说怎么写代码

编译的时候如何包含库文件这种事情就不说了.

第一步, 包含头文件.

#include <openssl/rsa.h>// 既然是RSA加密该头文件肯定是需要的#include <openssl/bn.h>// 这个头文件用于RSA的公钥私钥生成中, 生成大数用的#include <openssl/pem.h>// 这个是用于将公钥私钥保存成pem文件用的// 其它所需的头文件会被上述三个头文件自动包含, 比如bio.h

第二步, 生成公钥私钥文件

首先说明一下, 在RSA的私钥中, 既包含私钥信息也包含公钥信息

也就是说, 所谓的公钥, 其实就是私钥的一部分

要生成公钥私钥文件, 可是使用openssl的可执行文件openssl, 通过命令行的形式执行

# 生成私钥文件key.pem, 2048是密钥的位数openssl genrsa -out key.pem 2048# 基于私钥文件key.pem提取公钥文件key.pub.pemopenssl rsa -in key.pem -pubout -out key.pub.pem

除了上述使用工具, 也可以使用代码生成, 这里说一下代码生成的方法:

// 生成基本的RSA密钥数据很简单, 使用下面四句话即可RSA* rsa = RSA_new();BIGNUM* e = BN_new();BN_set_word(e, 65537);// 65537是官方推荐的一个数字, 其实任意素数都是可以的RSA_generate_key_ex(rsa, 2048, e, 0);// 2048表示密钥的位数, 可以是别的值, 但最好是4的倍数, 且至少为1024

接下来, 就是将生成的RSA密钥数据密钥保存为文件.

// 使用BIO打开密钥文件BIO* _pri = BIO_new_file("key.pem", "w");// 写入密钥PEM_write_bio_RSAPrivateKey(_pri, rsa, NULL, NULL, 0, NULL, NULL);// 使用BIO打开公钥文件BIO* _pub = BIO_new_file("key.pub.pem", "w"); // 写入公钥PEM_write_bio_RSAPublicKey(_pub, rsa);

最后, 不要忘记释放资源

BIO_free(_pub);BIO_free(_pri);BN_free(e);RSA_free(rsa);

第三步, 加密和解密数据

在如何编写代码之前, 对于RSA加密与解密需要额外的说一下, 那就是加密限制.

原理就不说了, 总的来说, RSA加密是存在内容长度的限制的, 简单的来说, 加密内容的长度, 最长只能是密钥的字节数-11. 当然, 这个前提是加密时, 使用了RSA_PKCS1_PADDING.

比如上面的步骤中, 我们生成了2048位的密钥, 也就是说, 密钥的字节数是512, 那么, 我们能够加密的内容就只有501个字节了. 如果密钥的字节数是256, 也就是1024位的时候, 那我们就只能加密245个字节了.

然后, 无论我们要加密多少数据, 最终生成的密文长度总是和密钥长度相等.

之后就是代码了, 关键的四个函数, 都比较简单: 就是从fromeBuffer加密或解密到toBuffer,

_len是fromBuffer中数据的长度, key是RSA*对象

返回值是加密或解密后的大小, -1表示失败

对了, 一定要注意:公钥加密后要用私钥解密, 私钥加密后需要用公钥解密

// 还记得加密限制嘛? 无论加密还是解密, 数据大小都不会超过密钥长度, // 密钥长度则可以通过RSA_size函数获取// key的类型为RSA *;unsigned char* _fromBuffer = new unsigned char[RSA_size(key)];unsigned char* _toBuffer = new unsigned char[RSA_size(key)];// 将需要加密或解密的内容复制到fromBuffer中, 然后使用以下代码进行加密或解密// 使用密钥加密size = RSA_private_encrypt(_len, _fromBuffer, _toBuffer, key, RSA_PKCS1_PADDING);// 使用公钥解密(只能解密对应密钥加密的内容)size = RSA_public_decrypt(_len, _fromBuffer, _toBuffer, key, RSA_PKCS1_PADDING);// 使用公钥加密size = RSA_public_encrypt(_len, _fromBuffer, _toBuffer, key, RSA_PKCS1_PADDING);// 使用密钥解密(只能解密对应公钥加密的内容)size = RSA_private_decrypt(_len, _fromBuffer, _toBuffer, key, RSA_PKCS1_PADDING);// 不要忘记清空缓存空间delete[] _fromBuffer;delete[] _toBuffer;

此时, 聪明的你应该就会产生疑问了, 这个RSA *key是哪里来的? 我们只有文件啊?

还记得将RSA写入文件的代码嘛? 稍微修改一下就是读取的代码啦!

BIO* keybio = BIO_new_file("xxxx.pem", "r");RSA* rsa = NULL;// 读取的时候, 我们需要区分是公钥还是私钥, 这个似乎没有办法自动判断, 所以可以总是先按照密钥读取, 失败了再当作公钥读取rsa = PEM_read_bio_RSAPrivateKey(keybio, &rsa, NULL, NULL);if (rsa == NULL){BIO_seek(keybio, 0);// 公钥文件需要使用读取公钥的函数rsa = PEM_read_bio_RSAPublicKey(keybio, &rsa, NULL, NULL);}BIO_free(keybio);

最后, 如果你足够聪明或者好奇心比较重, 应该会有以下的疑问: 既然第二步中解释了密钥中是存在公钥信息的, 并且一份RSA就可以生成两个文件, 那么我可以使用密钥进行公钥加密/解密吗?

当然可以啦, 只要我们有密钥, 就可以使用密钥加密解密以及公钥加密解密四个函数中的任意一个, 毕竟密钥中实际上是包含公钥的, 而有公钥时, 只能使用公钥加密解密这两个函数.

所以, 我们应该记住一个关键的事情:千万不要公开密钥而自己保留公钥

密钥之所以被称为密钥是有它的原因的.

额外的思考

RSA加密是存在长度限制的, 其长度与密钥位数有关, 那么, 如果我们想要加密更长的数据要怎么办呢? 难道无限扩展密钥的位数吗?

相信稍微有点经验的人都不会这么想吧. 那么稍微思考一下, 结论就很明显了.

分段加密就行啦!

我们只需要计算出来当前密钥允许加密的最大的字节数(使用RSA_PKCS1_PADDING就是密钥字节长度-11), 然后将需要加密的数据按照这个长度分段加密, 最后把加密的结果在拼接到一起, 就行了.

解密的时候, 则按照密钥长度将加密后的数据分段解密, 最后把解密结果拼接到一起, 就行了.

当然, RSA的速度是要比其它加密方式慢上很多的, 通常的用法是用通过RSA传递"对称加密的密钥与校验码". 当然, 对在速度不敏感的情况下, 我们就可以随意的按照自己的喜爱使用啦. 比如将自己的秘密文件加密…

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。