公钥,私钥和数字签名这样最好理解,以及加解密实例
⼀、公钥加密
假设⼀下,我了两个数字,⼀个是1,⼀个是2。我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉⼤家,1是我的公钥。我有⼀个⽂件,不能让别⼈看,我就⽤1加密了。别⼈到了这个⽂件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以⽤数字2,就是我的私钥,来解密。这样我就可以保护数据了。
我的好朋友x⽤我的公钥1加密了字符a,加密后成了b,放在⽹上。别⼈偷到了这个⽂件,但是别⼈解不开,因为别⼈不知道2就是我的私钥,
只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。
⼆、私钥签名
如果我⽤私钥加密⼀段数据(当然只有我可以⽤私钥加密,因为只有我知道2是我的私钥),结果所有的⼈都看到我的内容了,因为他们都知
道我的公钥是1,那么这种加密有什么⽤处呢?
但是我的好朋友x说有⼈冒充我给他发信。怎么办呢?我把我要发的信,内容是c,⽤我的私钥2,加密,加密后的内容是d,发给x,再告诉他
解密看是不是c。他⽤我的公钥1解密,发现果然是c。
这个时候,他会想到,能够⽤我的公钥解密的数据,必然是⽤我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。
这样我们就能确认发送⽅⾝份了。这个过程叫做数字签名。当然具体的过程要稍微复杂⼀些。⽤私钥来加密数据,⽤途就是数字签名。
总结:公钥和私钥是成对的,它们互相解密。
公钥加密,私钥解密。
私钥数字签名,公钥验证。
举例
⽐如有两个⽤户Alice和Bob,Alice想把⼀段明⽂通过双钥加密的技术发送给Bob,Bob有⼀对公钥和私钥,那么加密解密的过程如下:
1. Bob将他的公开密钥传送给Alice。
2. Alice⽤Bob的公开密钥加密她的消息,然后传送给Bob。
3. Bob⽤他的私⼈密钥解密Alice的消息。
上⾯的过程可以⽤下图表⽰,Alice使⽤Bob的公钥进⾏加密,Bob⽤⾃⼰的私钥进⾏解密。
例⼦和图出⾃《⽹络安全基础应⽤与标准第⼆版》
RSA
RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国⿇省理⼯学院)开发的。RSA取名来⾃开发他们三者的名字。RSA是⽬前最有影响⼒的公钥加密算法,它能够抵抗到⽬前为⽌已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于⼀个⼗分简单的数论事实:将两个⼤素数相乘⼗分容易,但那时想要对其乘积进⾏因式分解却极其困难,因此可以将乘积公开作为加密密钥。
openssl是⼀个功能强⼤的⼯具包,它集成了众多密码算法及实⽤⼯具。我们即可以利⽤它提供的命令台⼯具⽣成密钥、证书来加密解密⽂件,也可以在利⽤其提供的API接⼝在代码中对传输信息进⾏加密。
RSA是⼀个⾮对称加密算法。简单说来,⾮对称加密算法就是说加密解密⼀个⽂件需要有两个密钥,⼀个⽤来加密,为公钥,⼀个⽤来解密,为私钥。证书可以⽤来授权公钥的使⽤。
今天⼩研究了下openssl的rsa加密,其中主要涉及利⽤公钥和密钥加解密⽂件,没有涉及对证书的操作。想要集体了解的可以去:
---------------------------------------------------------------------------------------------------------------------
⾸先介绍下命令台下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 -
-in指定要加密的⽂件,-inkey指定密钥,-pubin表明是⽤纯公钥⽂件加密,-out为加密后的⽂件。
解密⽂件:
openssl rsautl -decrypt - -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
10char* my_encrypt(char *str,char *path_key);//加密
11char* my_decrypt(char *str,char *path_key);//解密
12int main(void){
13char *source="i like dancing !";
14char *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);
20if(ptr_en!=NULL){
21 free(ptr_en);
22 }
23if(ptr_de!=NULL){
24 free(ptr_de);
25 }
26return0;
27 }
28char *my_encrypt(char *str,char *path_key){
29char *p_en;
30 RSA *p_rsa;
31 FILE *file;
32int flen,rsa_len;
33if((file=fopen(path_key,"r"))==NULL){
33if((file=fopen(path_key,"r"))==NULL){
34 perror("open key file error");
35return NULL;
36 }
如何给文件加密37if((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);
40return 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);
46if(RSA_public_encrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_en,p_rsa,RSA_NO_PADDING)<0){
47return NULL;
48 }
49 RSA_free(p_rsa);
50 fclose(file);
51return p_en;
52 }
53char *my_decrypt(char *str,char *path_key){
54char *p_de;
55 RSA *p_rsa;
56 FILE *file;
57int rsa_len;
58if((file=fopen(path_key,"r"))==NULL){
59 perror("open key file error");
60return NULL;
61 }
62if((p_rsa=PEM_read_RSAPrivateKey(file,NULL,NULL,NULL))==NULL){
63 ERR_print_errors_fp(stdout);
64return 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);
69if(RSA_private_decrypt(rsa_len,(unsigned char *)str,(unsigned char*)p_de,p_rsa,RSA_NO_PADDING)<0){
70return NULL;
71 }
72 RSA_free(p_rsa);
73 fclose(file);
74return p_de;
75 }
⼀个⽐较奇怪的问题:
37、38⾏中为从⽂件中获取密钥,发现如果使⽤openssl提供的PEM_read_RSAPublicKey⽅法会⼀直失败。
估计是⽂件格式的问题~
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论