java中使用openssl生成的rsa公私钥进行数据加解密,C++ 使用openssl库实现RSA算法加解密(C++与Java相互加解密)...

C++ 使用openssl库实现与java交互的RSA算法加解密

项目需要,需要用C++后端 进行RSA算法加密,Web端(Java)进行解密。把之前遇到的问题整理一下。一步一坑,坑坑有惊喜。 能到这来,RSA算法原理就不细讲了 ,反正作为学渣我也不太懂。

背景:为了网络数据安全,Web端(Java)要求用RSA加密算法传数据,公钥加密私钥解密方式(RSA有公钥加密私钥解密、私钥加密公钥解密),公钥秘钥都有Java生成,格式都是pkcs#8,本文秘钥的长度为2048。

第一步:生成正确的秘钥格式

java给的公钥是字符串,但是真正加密的时候用的pkcs#8格式的秘钥。java公钥字符串

std::string publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxFGq9XJtuXmXh6nIYmhAmmd67RK5uIExhkd8YjPYJfqSqyMA/1G0KkxUaRlqf2A0vjn12341ZE/BcdVQ3AG9NYNfAJMYLpPobGqMHV6S7OhyvJjnqyZD8hr8StbyUgXtJ3VNyZ3uhzi7W8Dje7MfFdVz8xlsW+z17ffZCWMkznFMPHuKHDoPAztKoQ1Fq6YconTq2F7cSVnFc0jkLu6X/ihz5dcPiz90WjFEANWRauuVXB2MMgdsjIhBgV8XTRKoB6zUDWVtR9icRVlgpwJjcSL/5xnwzhmgpG7lnAWwA7KE0/zrOx2jj1PkfiBvmk+H5Iyo9kTUQ2jaOqWwEqycSwIDAQAB";

pkcs#8格式的公钥

std::string publicKey =“

-----BEGIN PUBLIC KEY-----

MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxFGq9XJtuXmXh6nIYmhA

mmd67RK5uIExhkd8YjPYJfqSqyMA/1G0KkxUaRlqf2A0vjnPcdw1ZE/BcdVQ3AG9

NYNfAJMYLpPobGqMHV6S7OhyvJjnqyZD8hr8StbyUgXtJ3VNyZ3uhzi7W8Dje7Mf

FdVz8xlsW+z17ffZCWMkznFMPHuKHDoPAztKoQ1Fq6YconTq2F7cSVnFc0jkLu6X

/ihz5dcPiz90WjFEANWRauuVXB2MMgdsjIhBgV8XTRKoB6zUDWVtR9icRVlgpwJj

cSL/5xnwzhmgpG7lnAWwA7KE0/zrOx2jj1PkfiBvmk+H5Iyo9kTUQ2jaOqWwEqyc

SwIDAQAB

-----END PUBLIC KEY-----

”;

第二步:C++ RSA加密,用openssl库实现

string encodeData="123456789";//需要加密的内容

publicKey //第一步生成 pkcs#8格式的公钥

vector res= rsa_encode(encodeData, publicKey )

{

std::vector encrypt_data;

BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1);

if (in == NULL)

{

return std::vector();

}

RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL);

BIO_free(in);

if (rsa == NULL) {

return std::vector();

}

int size = RSA_size(rsa);

encrypt_data.resize(size);

int ret = RSA_public_encrypt(

message.length(), (unsigned char*)message.c_str(),

(unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING);

RSA_free(rsa);

if (ret == -1) {

return std::vector();

}

return encrypt_data;

}

此时会生成密文,打印出来之后是乱码,莫惊慌。对生成的密文进行base64转换,C++代码实现

size//encrypt_data.size()

std::string encodedData = Base64((unsigned char*)encrypt_data, int size)

{

std::string _base64_table = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

int num = 0, bin = 0, i;

std::string _encode_result;

const unsigned char * current;

current = str;

while (bytes > 2) {

_encode_result += _base64_table[current[0] >> 2];

_encode_result += _base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];

_encode_result += _base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];

_encode_result += _base64_table[current[2] & 0x3f];

current += 3;

bytes -= 3;

}

if (bytes > 0)

{

_encode_result += _base64_table[current[0] >> 2];

if (bytes % 3 == 1) {

_encode_result += _base64_table[(current[0] & 0x03) << 4];

_encode_result += "==";

}

else if (bytes % 3 == 2) {

_encode_result += _base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];

_encode_result += _base64_table[(current[1] & 0x0f) << 2];

_encode_result += "=";

}

}

return _encode_result;

}

经过base64转化后的结果:

"Rn6yJNPLXZmMMWf7Rp6AURTiujNgnmpSFwzJLouXAPAgmS5ktyzGBCNF5/0ROG5PxHp+kLWfH25Kt0zhChXkuLWm3vmVGAXYfTVxBcPGqnEILnyiYIXnPpI3F5ahCPdXmHk0/+n3XNwWeHbEsX4ds7HuMT7Y3f9980FXGMwBXGGZiGKXIlHbJyBASgdjUq0F15igeVgKYIBXlIIAj8HT0Udmppd1mZDgdk/XbQIZ8okRJcdL37v53ogqkLyipoDJn1hJYLcL56nlNWxOK14oHpLCId3HjybhVUh2TVdTMQmQ4EVRE+OLGfVPCI9jILDxH4qQIvehJ9oma2EMDlwzbg=="

大功告成!此时生成的string传给Web端,java可以根据密文解码出加密的文本。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值