RSA是一种非对称加解密算法,所谓的非对称是指加密密钥和解密密钥不同,在初始化时将产生一个公钥和一个私钥的密钥对。其中私钥在本机安全区域存储,公钥可以在网络上进行明文传输。在双方需要对通信的内容进行加密时,由其中一方产生RSA密钥对,把公钥发送给对方,然后另一方收到后用公钥对内容进行加密,通过网络将密文发送给己方,己方收到后用私钥对密文进行解密。当然也可以由私钥进行加密,公钥进行解密,通常这种方式被称为签名与验证签名。
AES是一种常用的对称加密算法,加密密钥与解密密钥相同,又称共享密钥,相对RSA来说,AES密钥的加解密速率要快很多,因此通常将RSA和AES配合使用,其中使用RSA加密传输共享密钥,使用AES算法对传输的内容进行加解密。
OPENSSL是一个安全套接字层密码库,提供了RSA、AES等算法的C语言开发接口API,使用这些API可以方便的实现网络数据加解密的开发工作。
下面是一个使用RSA和AES进行密钥协商和加解密的例子的代码详解及运行结果,RSA采用2048bit的密钥,AES采用256bit的密钥,cbc方式。系统运行环境为CentOS 6.5,使用的开发编译环境为Eclipse。
1. 需要的头文件 #include "stdio.h"
#include "stdlib.h"
#include "openssl/rsa.h"
#include "openssl/pem.h"
#include "openssl/bn.h"
#include "string.h"
#include "openssl/bio.h"
#include "openssl/err.h"
#include "openssl/aes.h"
2. 产生 RSA 公钥 / 私钥,保存到 PEM 文件中
int rsa_gen_keys(const char *private_key_path/*私钥路径*/,const char *public_key_path/*公钥路径*/)
{
/*产生RSA密钥*/
RSA *rsa = RSA_new();
BIGNUM *e = BN_new();
/*设置随机数长度*/
BN_set_word(e,65537);
/*生成RSA密钥对*/
RSA_generate_key_ex(rsa,2048,e,NULL);
/*提取私钥*/
FILE *filename = NULL;
filename =fopen(private_key_path,"wb");
PEM_write_RSAPrivateKey(filename,rsa,NULL,NULL,0,NULL,NULL);
fclose(filename);
/*提取公钥*/
unsigned char *n_b = (unsigned char *)calloc(RSA_size(rsa),sizeof(unsigned char));
unsigned char *e_b = (unsigned char *)calloc(RSA_size(rsa),sizeof(unsigned char));
int n_size = BN_bn2bin(rsa->n,n_b);
int b_size = BN_bn2bin(rsa->e,e_b);
RSA *pubrsa = RSA_new();
pubrsa->n = BN_bin2bn(n_b,n_size,NULL);
pubrsa->e = BN_bin2bn(e_b,b_size,NULL);
filename =fopen(public_key_path,&#