RSA算法原理:http://blog.csdn.net/q376420785/article/details/8557266
下载安装编译Openssl:http://blog.csdn.net/fengyunzhongwei/article/details/44570917
使用Openssl命令台指令生成密钥:http://www.cnblogs.com/aLittleBitCool/archive/2011/09/22/2185418.html
---------------------------------------------------------------------------------------------------------------------------------------------------------
Openssl已经编译成功,如何在VS中调用Openssl的库函数:
1、创建一个项目,命名为RSA
2、添加头文件路径
点击菜单中“项目-->属性-->C/C++” 在 附加包含目录 中添加编译Openssl后生成的文件的头文件所在路径
3、添加库文件
点击菜单中“项目-->属性-->连接-->常规” 在 附加库目录 中添加生成的lib和dll文件所在的路径
添加完后还得在代码中调用静态链接库
---------------------------------------------------------------------------------------------------------------------------------------------
以下用C语言编程实现利用Openssl完成RSA加解密:
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "libeay32.lib")
#pragma comment(lib, "ssleay32.lib")
#define OPENSSLKEY "test.key" //文件为Openssl生成的密钥名字,得放在工程目录下
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
//extern "C"
//{
//#include
//};
char* my_encrypt(char *str, char *path_key);//加密
char* my_decrypt(char *str, char *path_key);//解密
int main(void) {
char *source = "i like dancing !";
char *ptr_en, *ptr_de;
printf("source is :%s\n", source);
ptr_en = my_encrypt(source, PUBLICKEY);
printf("after encrypt:%s\n", ptr_en);
ptr_de = my_decrypt(ptr_en, OPENSSLKEY);
printf("after decrypt:%s\n", ptr_de);
if (ptr_en != NULL) {
free(ptr_en);
}
if (ptr_de != NULL) {
free(ptr_de);
}
return 0;
}
char *my_encrypt(char *str, char *path_key) {
errno_t err;
char *p_en;
RSA *p_rsa;
FILE *file;
int flen, rsa_len;
if ((err = fopen_s(&file, path_key, "r")) != 0) {
perror("open key file error");
return NULL;
}
if ((p_rsa = PEM_read_RSA_PUBKEY(file, NULL, NULL, NULL)) == NULL) {
//if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){ // 换成这句死活通不过,无论是否将公钥分离源文件
ERR_print_errors_fp(stdout);
return NULL;
}
flen = strlen(str);
rsa_len = RSA_size(p_rsa);
p_en = ( char *)malloc(rsa_len + 1);
memset(p_en, 0, rsa_len + 1);
if (RSA_public_encrypt(rsa_len, (unsigned char *)str, (unsigned char*)p_en, p_rsa, RSA_NO_PADDING)<0) {
return NULL;
}
RSA_free(p_rsa);
fclose(file);
return p_en;
}
char *my_decrypt(char *str, char *path_key) {
errno_t err;
char *p_de;
RSA *p_rsa;
FILE *file;
int rsa_len;
if (( err= fopen_s(&file,path_key, "r"))!=0) {
perror("open key file error");
return NULL;
}
if ((p_rsa = PEM_read_RSAPrivateKey(file, NULL, NULL, NULL)) == NULL) {
ERR_print_errors_fp(stdout);
return NULL;
}
rsa_len = RSA_size(p_rsa);
p_de = ( char *)malloc(rsa_len + 1);
memset(p_de, 0, rsa_len + 1);
if (RSA_private_decrypt(rsa_len, (unsigned char *)str, (unsigned char*)p_de, p_rsa, RSA_NO_PADDING)<0) {
return NULL;
}
RSA_free(p_rsa);
fclose(file);
return p_de;
}
报错:OPENSSL_Uplink(0F5D2000,08): no OPENSSL_Applink
解决方法:用ssl库的时候要引入这个头文件:#include
fopen和fopen_s用法比较
在定义FILE * fp 之后,fopen的用法是: fp = fopen(filename,"w")。而对于fopen_s来说,还得定义另外一个变量errno_t err,然后err = fopen_s(&fp,filename,"w")。返回值的话,对于fopen来说,打开文件成功的话返回文件指针(赋值给fp),打开失败则返回NULL值;对于fopen_s来说,打开文件成功返回0,失败返回非0。
在vs编程中,经常会有这样的警告:warning C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use_CRT_SECURE_NO_WARNINGS. See online help for details. 是因为 fopen_s比fopen多了溢出检测,更安全一些。