C++使用openssl rsa进行加密、解密和签名验证

mac2024-08-19  59

一、RSA是一种非对称加密算法,一般在数据加密的过程中会使用公钥加密,私钥解密,在签名生成和验证过程中会使用私钥加密,公钥解密。

二、使用openssl生成公钥和私钥

1、生成私钥,保存在文件rsa_private_key.pem里面 openssl genrsa -out rsa_private_key.pem 1024 2、通过私钥生成公钥,保存在文件rsa_private_key.pem里面 openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

三、openssl公钥加密,私钥解密(私钥和公钥通过文件传进去),这里有一个注意点是在通过私钥解密的读取私钥信息时候使用的是PEM_read_bio_RSAPrivateKey,但是通过公钥加密读取公钥信息的时候使用的是PEM_read_bio_RSA_PUBKEY,而不是PEM_read_bio_RSAPublicKey。

// 通过公钥文件加密 std::vector<char> EncryptByPubkeyFile(const std::string& message, const std::string& pub_filename) { BIO* in = BIO_new(BIO_s_file()); if (in == NULL) { std::cout << "BIO_new failed" << std::endl; return std::vector<char>(); } BIO_read_filename(in, pub_filename.c_str()); RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl; return std::vector<char>(); } int size = RSA_size(rsa); std::vector<char> encrypt_data; 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) { std::cout << "RSA_public_encrypt failed" << std::endl; return std::vector<char>(); } return encrypt_data; } // 通过私钥文件解密 std::string DecryptByPrikeyFile(char* cipher, uint32_t len, const std::string& pri_file) { BIO* in = BIO_new(BIO_s_file()); if (in == NULL) { std::cout << "BIO_new failed" << std::endl; return ""; } BIO_read_filename(in, pri_file.c_str()); RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl; return ""; } int size = RSA_size(rsa); std::vector<char> data; data.resize(size); int ret = RSA_private_decrypt(len, (unsigned char*)cipher, (unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (ret == -1) { std::cout << "RSA_private_decrypt failed" << std::endl; return ""; } std::string decrypt_data(data.begin(), data.end()); return decrypt_data; }

四、openssl公钥加密,私钥解密(私钥和公钥通过字符串传进去)

// 通过公钥字符串进行加密 std::vector<char> EncryptByPubkeyString(const std::string& message, const std::string& pubkey) { BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1); if (in == NULL) { std::cout << "BIO_new_mem_buf failed" << std::endl; return std::vector<char>(); } RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl; return std::vector<char>(); } int size = RSA_size(rsa); std::vector<char> encrypt_data; 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) { std::cout << "RSA_public_encrypt failed" << std::endl; return std::vector<char>(); } return encrypt_data; } // 通过私钥字符串进行解密 std::string DecryptByPrikeyString(char* cipher, uint32_t len, const std::string prikey) { BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1); if (in == NULL) { std::cout << "BIO_new_mem_buf failed" << std::endl; return ""; } RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl; return ""; } int size = RSA_size(rsa); std::vector<char> data; data.resize(size); int ret = RSA_private_decrypt(len, (unsigned char*)cipher, (unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (ret == -1) { std::cout << "RSA_private_decrypt failed" << std::endl; return ""; } std::string decrypt_data(data.begin(), data.end()); return decrypt_data; }

五、openssl私钥加密,公钥解密(私钥和公钥通过文件传进去),一般用来生成和验证签名

// 通过私钥文件加密 std::vector<char> EncryptByPrikeyFile(const std::string& message, const std::string& pri_file) { BIO* in = BIO_new(BIO_s_file()); if (in == NULL) { std::cout << "BIO_new failed" << std::endl; return std::vector<char>(); } BIO_read_filename(in, pri_file.c_str()); RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl; return std::vector<char>(); } int size = RSA_size(rsa); std::vector<char> encrypt_data; encrypt_data.resize(size); int ret = RSA_private_encrypt( message.length(), (unsigned char*)message.c_str(), (unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (ret == -1) { std::cout << "RSA_private_encrypt failed" << std::endl; return std::vector<char>(); } return encrypt_data; } // 通过公钥文件解密 std::string DecryptByPubkeyFile(char* cipher, uint32_t len, const std::string& pub_filename) { BIO* in = BIO_new(BIO_s_file()); if (in == NULL) { std::cout << "BIO_new failed" << std::endl; return ""; } BIO_read_filename(in, pub_filename.c_str()); RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl; return ""; } int size = RSA_size(rsa); std::vector<char> data; data.resize(size); int ret = RSA_public_decrypt(len, (unsigned char*)cipher, (unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (ret == -1) { std::cout << "RSA_public_decrypt failed" << std::endl; return ""; } std::string decrypt_data(data.begin(), data.end()); return decrypt_data; }

六、openssl私钥加密,公钥解密(私钥和公钥通过字符串传进去),一般用来生成和验证签名

// 通过私钥字符串加密 std::vector<char> EncryptByPrikeyString(const std::string& message, const std::string& prikey) { BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1); if (in == NULL) { std::cout << "BIO_new_mem_buf failed" << std::endl; return std::vector<char>(); } RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl; return std::vector<char>(); } int size = RSA_size(rsa); std::vector<char> encrypt_data; encrypt_data.resize(size); int ret = RSA_private_encrypt( message.length(), (unsigned char*)message.c_str(), (unsigned char*)encrypt_data.data(), rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (ret == -1) { std::cout << "RSA_private_encrypt failed" << std::endl; return std::vector<char>(); } return encrypt_data; } // 通过公钥字符串解密 std::string DecryptByPubkeyString(char* cipher, uint32_t len, const std::string& pubkey) { BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1); if (in == NULL) { std::cout << "BIO_new_mem_buf failed" << std::endl; return ""; } RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl; return ""; } int size = RSA_size(rsa); std::vector<char> data; data.resize(size); int ret = RSA_public_decrypt(len, (unsigned char*)cipher, (unsigned char*)data.data(), rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (ret == -1) { std::cout << "RSA_public_decrypt failed" << std::endl; return ""; } std::string decrypt_data(data.begin(), data.end()); return decrypt_data; }

七、openssl私钥生成签名,公钥验证签名(私钥和公钥通过文件传进去),这里传进去的message是一个文件的md5值,所以在RSA_sign函数和RSA_verify函数的第一个参数使用NID_md5

// 通过私钥文件生成签名 std::vector<char> GenerateRsaSignByFile(const std::string& message, const std::string& pri_filename) { OpenSSL_add_all_algorithms(); BIO* in = BIO_new(BIO_s_file()); if (in == NULL) { std::cout << "BIO_new failed" << std::endl; return std::vector<char>(); } BIO_read_filename(in, pri_filename.c_str()); RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl; return std::vector<char>(); } unsigned int size = RSA_size(rsa); std::vector<char> sign; sign.resize(size); int ret = RSA_sign(NID_md5, (const unsigned char*)message.c_str(), message.length(), (unsigned char*)sign.data(), &size, rsa); RSA_free(rsa); if (ret != 1) { std::cout << "RSA_sign failed" << std::endl; return std::vector<char>(); } return sign; } // 通过公钥文件验证签名 bool VerifyRsaSignByFile(char* sign, uint32_t sign_len, const std::string& pub_filename, const std::string& verify_str) { OpenSSL_add_all_algorithms(); BIO* in = BIO_new(BIO_s_file()); if (in == NULL) { std::cout << "BIO_new failed" << std::endl; return false; } BIO_read_filename(in, pub_filename.c_str()); RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); if (rsa == NULL) { std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl; return false; } BIO_free(in); int ret = RSA_verify(NID_md5, (const unsigned char*)verify_str.c_str(), verify_str.length(), (unsigned char*)sign, sign_len, rsa); RSA_free(rsa); if (ret != 1) { std::cout << "RSA_verify failed" << std::endl; return false; } return true; }

八、openssl私钥生成签名,公钥验证签名(私钥和公钥通过字符串传进去)

// 通过私钥字符串生成签名 std::vector<char> GenerateRsaSignByString(const std::string& message, const std::string& prikey) { OpenSSL_add_all_algorithms(); BIO* in = BIO_new_mem_buf((void*)prikey.c_str(), -1); if (in == NULL) { std::cout << "BIO_new_mem_buf failed" << std::endl; return std::vector<char>(); } RSA* rsa = PEM_read_bio_RSAPrivateKey(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSAPrivateKey failed" << std::endl; return std::vector<char>(); } unsigned int size = RSA_size(rsa); std::vector<char> sign; sign.resize(size); int ret = RSA_sign(NID_md5, (const unsigned char*)message.c_str(), message.length(), (unsigned char*)sign.data(), &size, rsa); RSA_free(rsa); if (ret != 1) { std::cout << "RSA_sign failed" << std::endl; return std::vector<char>(); } return sign; } // 通过公钥字符串验证签名 bool VerifyRsaSignByString(char* sign, uint32_t sign_len, const std::string& pubkey, const std::string& verify_str) { BIO* in = BIO_new_mem_buf((void*)pubkey.c_str(), -1); if (in == NULL) { std::cout << "BIO_new_mem_buf failed" << std::endl; return false; } RSA* rsa = PEM_read_bio_RSA_PUBKEY(in, NULL, NULL, NULL); BIO_free(in); if (rsa == NULL) { std::cout << "PEM_read_bio_RSA_PUBKEY failed" << std::endl; return false; } int ret = RSA_verify(NID_md5, (const unsigned char*)verify_str.c_str(), verify_str.length(), (unsigned char*)sign, sign_len, rsa); RSA_free(rsa); if (ret != 1) { std::cout << "RSA_verify failed" << std::endl; return false; } return true; }

九、全部代码下载

https://github.com/yangpan4485/openssl_rsa

最新回复(0)