红联Linux门户
Linux帮助

利用OpenSSL进行RSA加密解密

发布时间:2015-02-15 10:51:46来源:linux网站作者:linux人

OpenSSL是一个功能强大的工具包,它集成了众多密码算法及实用工具。我们即可以利用它提供的命令台工具生成密钥、证书来加密解密文件,也可以在利用其提供的API接口在代码中对传输信息进行加密。

RSA是一个非对称加密算法。简单说来,非对称加密算法就是说加密解密一个文件需要有两个密钥,一个用来加密,为公钥,一个用来解密,为私钥。证书可以用来授权公钥的使用。

今天小研究了下OpenSSL的RSA加密,其中主要涉及利用公钥和密钥加解密文件,没有涉及对证书的操作。想要集体了解的可以去:

http://www.OpenSSL.org/


首先介绍下命令台下OpenSSL工具的简单使用:

生成一个密钥:

openssl genrsa -out test.key 1024

这里-out指定生成文件的。需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密。后面的1024是生成密钥的长度。

openssl可以将这个文件中的公钥提取出来:

openssl rsa -in test.key -pubout -out test_pub.key

-in指定输入文件,-out指定提取生成公钥的文件名。至此,我们手上就有了一个公钥,一个私钥(包含公钥)。现在可以将用公钥来加密文件了。

我在目录中创建一个hello的文本文件,然后利用此前生成的公钥加密文件:

openssl rsautl -encrypt -in hello -inkey test_pub.key -pubin -out hello.en

-in指定要加密的文件,-inkey指定密钥,-pubin表明是用纯公钥文件加密,-out为加密后的文件。

解密文件:

openssl rsautl -decrypt -in hello.en -inkey test.key -out hello.de

-in指定被加密的文件,-inkey指定私钥文件,-out为解密后的文件。

至此,一次加密解密的过程告终。在实际使用中还可能包括证书,这个以后有机会再说~


下来介绍下在程序如何利用之前生成的test.key和test_pub.key来进行信息的加密与解密(当然也可以直接利用openssl的API来生成密钥文件)。

下面是一个例子,这个例子利用已有的密钥来对source字符串进行加密与解密:

 1 #include<stdio.h>
2 #include<stdlib.h> 3 #include<string.h>
4 #include<openssl/rsa.h>
5 #include<openssl/pem.h>
6 #include<openssl/err.h>
7 #define OPENSSLKEY "test.key"
8 #define PUBLICKEY "test_pub.key" 9 #define BUFFSIZE 1024
10 char* my_encrypt(char *str,char *path_key);//加密
11 char* my_decrypt(char *str,char *path_key);//解密
12 int main(void){
13    char *source="i like dancing !";
14    char *ptr_en,*ptr_de;
15    printf("source is    :%s\n",source);
16    ptr_en=my_encrypt(source,PUBLICKEY);
17    printf("after encrypt:%s\n",ptr_en);
18 ptr_de=my_decrypt(ptr_en,OPENSSLKEY); 19    printf("after decrypt:%s\n",ptr_de);
20    if(ptr_en!=NULL){
21        free(ptr_en);
22    }
23    if(ptr_de!=NULL){
24        free(ptr_de);
25    }
26    return 0;
27 }
28 char *my_encrypt(char *str,char *path_key){
29    char *p_en;
30    RSA *p_rsa;
31    FILE *file;
32    int flen,rsa_len;
33    if((file=fopen(path_key,"r"))==NULL){
34        perror("open key file error");
35        return NULL;  
36    }
37    if((p_rsa=PEM_read_RSA_PUBKEY(file,NULL,NULL,NULL))==NULL){
38    //if((p_rsa=PEM_read_RSAPublicKey(file,NULL,NULL,NULL))==NULL){  换成这句死活通不过,无论是否将公钥分离源文件
39         ERR_print_errors_fp(stdout);
40        return NULL;
41    }
42    flen=strlen(str);
43    rsa_len=RSA_size(p_rsa);
44    p_en=(unsigned char *)malloc(rsa_len+1);
45    memset(p_en,0,rsa_len+1);
46    if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){
47        return NULL;
48    }
49    RSA_free(p_rsa);
50    fclose(file);
51    return p_en;
52 }
53 char *my_decrypt(char *str,char *path_key){
54    char *p_de;
55    RSA *p_rsa;
56    FILE *file;
57    int rsa_len;
58    if((file=fopen(path_key,"r"))==NULL){
59        perror("open key file error");
60        return NULL;
61    }
62    if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
63        ERR_print_errors_fp(stdout);
64        return NULL;
65    }
66    rsa_len=RSA_size(p_rsa);
67    p_de=(unsigned char *)malloc(rsa_len+1);
68    memset(p_de,0,rsa_len+1);
69    if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){
70        return NULL;
71    }
72    RSA_free(p_rsa);
73    fclose(file);
74    return p_de;
75 }


一个比较奇怪的问题:

37、38行中为从文件中获取密钥,发现如果使用openssl提供的PEM_read_RSAPublicKey方法会一直失败。

估计是文件格式的问题。