背景:
rsa作为数字签名和数据加密来说是通常都会使用的,而不免有些是不同语言来做的,这里主要是用于数据加密。
java客户端使用的rsa加密padding方式为RSA/ECB/OAEPWithSHA256AndMGF1Padding方式(这里要说明一下:RSA/ECB/OAEPWithSHA256AndMGF1Padding和RSA/ECB/OAEPWithSHA-256AndMGF1Padding是由Bouncy Castle和SUN JCE提供的,这两者通常情况可能java可以兼容,但有时基于硬件和软件区别编译会有不可预测的报错)。查看c++的openssl标准库没有这种加密方式
问题:
1.openssl现在的padding方式为RSA_PKCS1_PADDING, RSA_PKCS1_OAEP_PADDING, RSA_NO_PADDING,这三种都是常见的padding方式,每种的使用注意事项现在网络上由这大量的资源做参考,但是java所使用的RSA/ECB/OAEPWithSHA256AndMGF1Padding方式是不同的,在openssl标准库中并没有这一算法的接口。
2.查阅各种资料,最后显示在botan库中实现了这一加密方式,并查看了其实现源码,大体思路为首先读文件或者是读取字符串的公钥私钥,做加解密,注意公钥方式一定是X509格式的,而私钥一定是PKCS8格式,密钥格式的转换还是推荐使用openssl的来做转换。
openssl pkcs8 -topk8 -inform PEM -in private.pem -outform pem -nocrypt -out pkcs8.pem
读取进来后对文本内容做加解密计算,通过base64或者hex进行格式化输出。查看源代码文件看算法实现,一个具体demo如下:
//text to decrypt
std::vector<uint8_t> pt(plaintext.data(),plaintext.data()+plaintext.length());
std::unique_ptr<Botan::RandomNumberGenerator> rng(new Botan::AutoSeeded_RNG);
//load pri key
Botan::DataSource_Memory key_in(fixed_rsa_key);
//go decrypt
std::unique_ptr<Botan::Private_Key> pk(Botan::PKCS8::load_key(key_in,*rng.get()));
Botan::PK_Decryptor_EME dec(*pk,*rng.get(), “EME1(SHA-256)”);
std::cout <<“dec:”<< Botan::hex_encode(dec.decrypt(pt));
3.botan库中新版本存在一个问题就是必须要使用到libc库的新版本,原因是辅助向量(auxiliary vector),这个一直以来都是开放管理的,glibc库在2.6之后对这个变量增加了新的库函数getauxval(),获取到需要的glibc库,汇编器as该版本也不能兼容老版,需要更新binutils。
4.botan库的最终结果做base64或者hex转为明文即我们所需要的string输出格式,但是私钥的pkcs1的格式是不支持的,翻阅源码你会发现根本没有pkcs1格式的私钥,需要用上述方法转换为对应的pkcs8格式,再做传入
如果看完觉得有所收获的话,记得点赞关注哦