openssl编程之rsa加解密
测试代码:
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#include <string.h>
void handle_openssl_errors() {
ERR_print_errors_fp(stderr);
abort();
}
RSA* load_public_key_from_file(const char* filename) {
BIO* bio = BIO_new_file(filename, "r");
if (!bio) return NULL;
RSA* rsa = PEM_read_bio_RSA_PUBKEY(bio, NULL, NULL, NULL);
BIO_free(bio);
return rsa;
}
RSA* load_private_key_from_file(const char* filename) {
BIO* bio = BIO_new_file(filename, "r");
if (!bio) return NULL;
RSA* rsa = PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
BIO_free(bio);
return rsa;
}
int openssl_rsa() {
// 初始化 OpenSSL
OpenSSL_add_all_algorithms();
ERR_load_crypto_strings();
RSA* rsa_key = NULL;
FILE* fp = NULL;
const char* plaintext = "this is xiaohai";
int plaintext_len = strlen(plaintext);
// 用于存储加密后的数据和解密后的数据
unsigned char encrypted[4098] = {};
unsigned char decrypted[4098] = {};
int encrypted_len, decrypted_len;
#if 0
// 1. 使用公钥加密
printf("1. Encrypting with public key...\n");
fp = fopen("pub.pem", "r");
if (!fp) {
perror("Error opening public key file");
handle_openssl_errors();
}
// 从文件加载公钥
rsa_key = PEM_read_RSA_PUBKEY(fp, &rsa_key, NULL, NULL);
fclose(fp);
if (!rsa_key) {
fprintf(stderr, "Error reading public key\n");
handle_openssl_errors();
}
#endif
rsa_key=load_public_key_from_file("pub.pem");
// 执行加密
// RSA_PKCS1_OAEP_PADDING 是推荐的现代填充方式,比 RSA_PKCS1_PADDING 更安全
encrypted_len = RSA_public_encrypt(plaintext_len,
(unsigned char*)plaintext,
encrypted,
rsa_key,
RSA_PKCS1_OAEP_PADDING);
if (encrypted_len == -1) {
fprintf(stderr, "Error encrypting message\n");
handle_openssl_errors();
}
printf("Encryption successful. Encrypted length: %d\n", encrypted_len);
// 释放公钥结构体
RSA_free(rsa_key);
rsa_key = NULL;
#if 0
// 2. 使用私钥解密
printf("\n2. Decrypting with private key...\n");
fp = fopen("pri.pem", "r");
if (!fp) {
perror("Error opening private key file");
handle_openssl_errors();
}
// 从文件加载私钥
rsa_key = PEM_read_RSAPrivateKey(fp, &rsa_key, NULL, NULL);
fclose(fp);
if (!rsa_key) {
fprintf(stderr, "Error reading private key\n");
handle_openssl_errors();
}
#endif
rsa_key = load_private_key_from_file("pri.pem");
// 执行解密
decrypted_len = RSA_private_decrypt(encrypted_len,
encrypted,
decrypted,
rsa_key,
RSA_PKCS1_OAEP_PADDING);
if (decrypted_len == -1) {
fprintf(stderr, "Error decrypting message\n");
handle_openssl_errors();
}
// 添加字符串终止符并打印结果
decrypted[decrypted_len] = '\0';
printf("Decryption successful. Decrypted text: '%s'\n", decrypted);
// 清理
RSA_free(rsa_key);
EVP_cleanup();
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
return 0;
}