使用c++编写一个非对称加密的解密与加密程序
时间: 2024-06-11 20:10:38 浏览: 165
非对称加密是一种公开密钥加密方式,它使用两个密钥,一个是公开密钥,另一个是私有密钥。公开密钥可以公开给任何人,私有密钥只有密钥持有者才能拥有。使用公开密钥加密的消息只能使用相应的私有密钥进行解密。这种加密方式在安全性上相对对称加密更高,但是由于加密和解密的计算量比较大,因此通常不用于加密大量数据。
下面是一个使用RSA算法实现非对称加密和解密的C语言程序:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define KEY_LENGTH 2048
#define PUB_KEY_FILE "public_key.pem"
#define PRI_KEY_FILE "private_key.pem"
int generate_key_pair()
{
RSA *rsa = NULL;
FILE *fp = NULL;
int ret = 0;
// 生成RSA密钥对
rsa = RSA_new();
if (rsa == NULL)
{
printf("RSA_new failed.\n");
return -1;
}
BIGNUM *bne = BN_new();
ret = BN_set_word(bne, RSA_F4);
if (ret != 1)
{
printf("BN_set_word failed.\n");
RSA_free(rsa);
return -1;
}
ret = RSA_generate_key_ex(rsa, KEY_LENGTH, bne, NULL);
if (ret != 1)
{
printf("RSA_generate_key_ex failed.\n");
RSA_free(rsa);
return -1;
}
// 保存公钥
fp = fopen(PUB_KEY_FILE, "w");
if (fp == NULL)
{
printf("open %s failed.\n", PUB_KEY_FILE);
RSA_free(rsa);
return -1;
}
ret = PEM_write_RSAPublicKey(fp, rsa);
fclose(fp);
if (ret != 1)
{
printf("PEM_write_RSAPublicKey failed.\n");
RSA_free(rsa);
return -1;
}
// 保存私钥
fp = fopen(PRI_KEY_FILE, "w");
if (fp == NULL)
{
printf("open %s failed.\n", PRI_KEY_FILE);
RSA_free(rsa);
return -1;
}
ret = PEM_write_RSAPrivateKey(fp, rsa, NULL, NULL, 0, NULL, NULL);
fclose(fp);
if (ret != 1)
{
printf("PEM_write_RSAPrivateKey failed.\n");
RSA_free(rsa);
return -1;
}
RSA_free(rsa);
return 0;
}
int encrypt_data(const char *plain_data, size_t data_len, char *encrypted_data, size_t *encrypted_len)
{
RSA *rsa = NULL;
FILE *fp = NULL;
int ret = 0;
// 加载公钥
fp = fopen(PUB_KEY_FILE, "r");
if (fp == NULL)
{
printf("open %s failed.\n", PUB_KEY_FILE);
return -1;
}
rsa = PEM_read_RSAPublicKey(fp, NULL, NULL, NULL);
fclose(fp);
if (rsa == NULL)
{
printf("PEM_read_RSAPublicKey failed.\n");
return -1;
}
// 加密数据
*encrypted_len = RSA_size(rsa);
ret = RSA_public_encrypt(data_len, (unsigned char *)plain_data, (unsigned char *)encrypted_data, rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret <= 0)
{
printf("RSA_public_encrypt failed.\n");
return -1;
}
return 0;
}
int decrypt_data(const char *encrypted_data, size_t encrypted_len, char *decrypted_data, size_t *decrypted_len)
{
RSA *rsa = NULL;
FILE *fp = NULL;
int ret = 0;
// 加载私钥
fp = fopen(PRI_KEY_FILE, "r");
if (fp == NULL)
{
printf("open %s failed.\n", PRI_KEY_FILE);
return -1;
}
rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
fclose(fp);
if (rsa == NULL)
{
printf("PEM_read_RSAPrivateKey failed.\n");
return -1;
}
// 解密数据
*decrypted_len = RSA_size(rsa);
ret = RSA_private_decrypt(encrypted_len, (unsigned char *)encrypted_data, (unsigned char *)decrypted_data, rsa, RSA_PKCS1_PADDING);
RSA_free(rsa);
if (ret <= 0)
{
printf("RSA_private_decrypt failed.\n");
return -1;
}
return 0;
}
int main()
{
int ret = 0;
char plain_data[] = "Hello World!";
size_t data_len = strlen(plain_data);
char encrypted_data[KEY_LENGTH / 8] = { 0 };
size_t encrypted_len = 0;
char decrypted_data[KEY_LENGTH / 8] = { 0 };
size_t decrypted_len = 0;
// 生成RSA密钥对
ret = generate_key_pair();
if (ret != 0)
{
printf("generate_key_pair failed.\n");
return -1;
}
// 加密数据
ret = encrypt_data(plain_data, data_len, encrypted_data, &encrypted_len);
if (ret != 0)
{
printf("encrypt_data failed.\n");
return -1;
}
// 解密数据
ret = decrypt_data(encrypted_data, encrypted_len, decrypted_data, &decrypted_len);
if (ret != 0)
{
printf("decrypt_data failed.\n");
return -1;
}
// 打印结果
printf("plain_data: %s\n", plain_data);
printf("encrypted_data: ");
for (size_t i = 0; i < encrypted_len; i++)
{
printf("%02X ", encrypted_data[i]);
}
printf("\n");
printf("decrypted_data: %s\n", decrypted_data);
return 0;
}
```
这个程序的主要流程如下:
1. 使用RSA_generate_key_ex函数生成RSA密钥对,并将公钥和私钥保存到文件中;
2. 加载公钥并使用RSA_public_encrypt函数加密数据;
3. 加载私钥并使用RSA_private_decrypt函数解密数据。
在编译时需要链接OpenSSL库,使用命令`gcc -o rsa_test rsa_test.c -lssl -lcrypto`即可。注意,程序每次运行都会生成新的RSA密钥对,因此不要在生产环境中使用这个程序,应该使用事先生成好的密钥对。
阅读全文