对称加密和非对称加密

加密方式:

对称加密 非对称加密
原理 用一个钥匙去加密数据,解密时也必须使用那把用于加密的钥匙。 每个人都有2把钥匙,一个是公钥(可以给任何人),一个是私钥(必须自己拥有)。用公钥加密的数据,只能用私钥解密;用私钥加密的数据,只能用公钥解密。
算法种类 DES,3DES,Blowfish,RC5,IDEA RSA(加密,数字签名),DSA(只能做数字签名),Elgamal,ECC(椭圆曲线加密算法),Rabin,D-H
优点 加密,解密速度快 1,公钥随便分发;2,可以验证是谁发的;3,只需管理自己的公钥和私钥。
缺点 1,密钥分发困难;2,无法验证是谁发的;3,要管理很多钥匙,每给一个人发,就需要一把和以前不一样的钥匙 解密速度和对称加密比,极慢。
加密解密所有时间 假设使用DES算法,对1G数据,加密需要4分钟,解密需要8分钟,加密后的数据变成2G。 假设使用RSA算法,对1G数据,加密需要1分钟,解密需要64小时,加密后的数据还是1G。

使用非对称加密,解决加密问题的方法:

  • 案例1 :小王有公钥m,私钥n;小李有公钥x,私钥y。现在小王要给小李发送数据,要求加密,而且只有小李才能解密,如何做呢?

    小王用小李的公钥x加密数据,然后把加密后的数据发送给小李,小李使用自己的私钥y可以机密,没有私钥y的人无法解密。

  • 案例2:在案例1中,小李虽然能解密,但是不知道这个数据到底是不是小王发过来的。那么如何解决呢?

    小王先用自己的私钥m加密数据得到data1(m(data)=data1),data1就是小王的数字签名,相当于盖了个章;然后再用小李的公钥x加密data1得到data2(data2=x(data1)),然后把data2发给小李;小李拿到数据后,先使用自己的私钥y解开data2,得到data1,然后再用小王的公钥n,解开data1,得到data。所有就实现了,既把数据加密,而且还能验证身份。

  • 案例3:在案例2中,还有2个问题

    • 如何得知data没有被篡改过呢,也就是如何得知数据是完整的呢?
    • 如果data很大,则解密需要的时间太长了。

    需要使用下面介绍的单向散列(数字摘要)的知识。

    第一种解决方案:x{data+n{hash(data)}}

    小王用hash运算,计算data的出hash值,在用他的私钥加密data的hash值,最后再用小李的公钥加密(data+加密过的hash值)。

    • n{hash(data)是为了保证数据来源于小王。
    • hash(data)是为了保证数据的完整性,没有被篡改过。
    • x{data+n{hash(data)}}是为了只让小李能够解密。

    这个解决方案的好处是,小王只加密data的hash值,hash值跟data比,小得多,加快了小李的解密速度。但是,还是用小李的公钥加密了data+hash值,所以小李解密还是慢。

    第二种解决方案:key{data+n{hash(data)}}+x(key)

    使用对称加密的方式,加密data+data的hash值;用非对称的方式加密对称加密时的密钥。

    小李拿到加密数据后,先用自己的私钥y解密x(key),得到对称加密使用的key;再用此key解密key{data+n{hash(data)}},得到data+n{hash(data)},注意,此处是用对称方式解密,所以非常快;再用小王的公钥m解密n{hash(data)}得到,data的hash值(能够解开则说明来源是小王,所以来源没问题),再用同样的散列算法,计算出data的hash值,对比计算出来的hash值和解密得到的hash值是否一样,一样则说明数据没有被篡改过。而且即使别人拿到了加密的数据,由于没有小李的私钥,所以无法解密得到key。

单向散列hash算法(数字摘要)

对一个数据做hash运算,不管这个数据的大小多大,运算后的结果叫hash值,hash值都是固定长度的串。并且有雪崩效果,即使修改一点数据的内容,运算后得出的hash值都面目全非,所以无法从hash值推到出数据。

hash算法:MD5(128bits),sha1(160bits),sha224,sha256,sha384,sha512

hash(data) = digest

计算数据的hash值的命令

sha1sum sha224sum sha256sum sha384sum sha512sum sharesec

检查hash值是否发生变化:--check

[root@localhost ~]# echo 222 > f1
[root@localhost ~]# sha256sum f1 > f1.256
[root@localhost ~]# cat f1.256
8f8eea956d0ea50d6442fdab213326f75bb6f584268b0795ad452faa85db5f9d  f1
[root@localhost ~]# sha256sum --check f1.256
f1: OK
[root@localhost ~]# echo 333 > f1
[root@localhost ~]# sha256sum --check f1.256
f1: FAILED
sha256sum: WARNING: 1 computed checksum did NOT match

反思yum和rpm安装包时,如何检查包的完整性的呢?如何检测来源的真实性呢?

来源真实性不用检查,因为是从官网和信得过镜像网站下载rpm,或者信得过的yum仓库。

完整性检查使用centos给提供的公钥去解密,得到hash值,然后计算包的hash值,一样的话,说明完整性没有问题。

centos的公钥在哪里呢?/etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7

使用:rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7导入公钥后,就可验证包的完整性了。

验证包完整性的命令:rpm -V 包名

安装包的时候,把每个安装的文件的hash值都存储起来了,所以可以使用rpm -V去检证。

验证bash,没发现问题,说明没有被修改过。

验证httpd,发现有修改过,修改过的文件也列出来了。

# rpm -V bash
# rpm -V httpd
S.5....T.  c /etc/httpd/conf/httpd.conf

对称密钥如何定期更换呢?

我们知道对称密钥的很难分发,可以使用非对称方式,加密对称的密钥。还有没有别的办法?

使用DH(Deffie-Hellman)算法。

有A和B2个人,他们已经互相都有了对称密钥,现在想更换对称密钥。

1,A和B协商使用2个整数a和p,a是整数,p是大的素数

2,A生成隐私数据x,x必须小于p,计算a^x%p,把计算结果发给B(不怕别别人看到)

3,B生成隐私数据y,计算a^y%p,把计算结果发给A(不怕别别人看到)

4,A拿到y,计算[(ay%p)x]%p = a^xy%p

5,B拿到x,计算[(ax%p)y]%p = a^xy%p

6,A和B得到同样的值,就把这个值作为新的对称密钥使用。

使用gpg实现对称加密

  • 加密:gpg -c file

    会弹出一个窗口,让你输入密钥,输入2次,并生成file.gpg文件。

  • 解密:gpg -o file -d file.gpg

    会弹出一个窗口,让你输入密钥。解密成功的话生成file文件。

使用gpg实现非对称加密

1,在机器A上,使用gpg --list-keys生成公钥和私钥

如果执行gpg --gen-key出现下面错误:

gpg: problem with the agent: No pinentry
gpg: Key generation canceled.

执行:unset DISPLAY

在centos6上生成时,需要敲键盘很多次,和移动鼠标,目的是生成随机数。

2,查看生成的公钥和私钥

# gpg --list-key laoyao
pub   1024R/70818978 2020-03-01
uid                  laoyao
sub   1024R/A9CFC54E 2020-03-01

3,导出公钥:

选项-a:导出的公钥是文本格式,不加-a则是二进制格式。

选项-o:把公钥写入到哪个文件。

选项--export:导出公钥。后面可以加名字,不加的话就是导出全部公钥。

注意名字不能加在--export后面。这里的laoyao就是公钥的名字。

# gpg -a --export -o laoyao.key laoyao

4,把公钥发给机器B

# scp laoyao.key root@192.168.56.106:/root

5,在机器B上导入在机器A上生成的公钥

# gpg --import laoyao.key
gpg: key 70818978: public key "laoyao" imported
gpg: Total number processed: 1
gpg:               imported: 1  (RSA: 1)
# gpg --list-keys
/root/.gnupg/pubring.gpg
------------------------
pub   1024R/37772C75 2020-03-01
uid                  aaaaa
sub   1024R/AA509546 2020-03-01

pub   1024R/70818978 2020-03-01
uid                  laoyao
sub   1024R/A9CFC54E 2020-03-01

6,使用机器A的公钥laoyao,加密机器B上的某个文件

选项-r就是指定使用哪个key加密,加密后生成f1.gpg文件。

# gpg -e -r laoyao f1
gpg: A9CFC54E: There is no assurance this key belongs to the named user

pub  1024R/A9CFC54E 2020-03-01 laoyao
 Primary key fingerprint: AEBA F8F6 7C61 5593 63FD  F148 A323 ACB1 7081 8978
      Subkey fingerprint: DF89 C575 1EAB 9112 5CFC  6C56 E23F C200 A9CF C54E

It is NOT certain that the key belongs to the person named
in the user ID.  If you *really* know what you are doing,
you may answer the next question with yes.

Use this key anyway? (y/N) y
# ll f1*
-rw-r--r--. 1 root root  12 Mar  1 16:20 f1
-rw-r--r--. 1 root root 213 Mar  1 16:21 f1.gpg

7,把f1.gpg传给机器A

# scp f1.gpg root@192.168.56.107:/root

8,在机器A上解密:

# gpg -o f1 -d f1.gpg
gpg: encrypted with 1024-bit RSA key, ID A9CFC54E, created 2020-03-01
      "laoyao"
[root@localhost ~]# cat f1
aaa
ddd
ddd
  • 删除公钥:gpg --delete-keys BBBBB
  • 删除私钥:gpg --delete-secret-keys BBBBB
# c/c++ 学习互助QQ群:877684253 ![](https://img2018.cnblogs.com/blog/1414315/201811/1414315-20181106214320230-961379709.jpg) # 本人微信:xiaoshitou5854
原文地址:https://www.cnblogs.com/xiaoshiwang/p/12392568.html