使用GPG学习非对称加密
2016-03-16 03:27
190 查看
非对称加密需要公钥和私钥:
公钥的作用:别人用来给你发加密的信息&别人验证你的签名
私钥的作用:你用来创建签名&解密别人发给你的信息的
具体而言,A要想发送加密信息到B,则:
A有A的签名私钥和B的加密公匙
B有A的签名公匙和B的加密私钥
使用GPG可以很好的演示这一点:
首先,我们在安装好GPG之后(安装步骤https://www.gnupg.org/howtos/zh/index.html),可以使用
以上就是我的公钥,其中
之后,我们需要得到别人的公钥,才能用他的公钥加密我们想要发给他的数据。
我们可以通过
说明我现在有两个公钥,一个是我自己的,另一个是Justin的。钥匙号分别为DAEDCB5B和C9C40C31,说到钥匙号,我们也可以使用别人的公钥钥匙号导入公钥
如果此时Justin用自己的私钥给文件签名(假设签名后的文件为sample.txt.asc,关于签名的内容我们会在最后再说)然后发给我,那么我就可以用公钥去验证文件签名的真伪:
以上信息可以看出,我们使用Justin的公钥可以认证这个文件,且文件的内容未曾被更改。但是有警告信息,这些信息是在告诉我们:如果这把公钥真的是Justin的,那么这个文件就是Justin的,但是这把公钥的真伪并没有的到验证,可能存在我们当初得到的公钥是被别人替换过的公钥的情况。为此,我们应当跟Justin本人确认此公钥的正确性,如果确认无误,我们可以对这个公钥进行信任程度设置(稍后再讲信任度的设置)。
接下来看使用GPG加密与解密的过程:
首先,我们写一些话,想要发给Justin(Hello.txt):
既然我们想发给Justin,那么我们自然需要用Justin的公钥对其进行加密(然后Justin再用自己的私钥对我发过去的加密内容进行解密),加密使用到的命令是
以上可以看出,虽然我们对内容进行了加密,但是由于我们还没有对公钥进行信任度设置,gpg仍在提醒我们公钥本身有可能就是假的。
接下来看看加密后的内容(Hello.txt.gpg):
乱码,因为这是二进制文件。
试试在加密过程中加入
接下来再查看加密后的文件(Hello.txt.asc):
虽然是字符,但显然内容已经被加密了,无法看懂。
我们把加密后的信息发给Justin之后,他直接用自己的私钥解密就可以阅读我们想给他传达的信息了(但是我无法演示解密过程,因为我没有Justin的私钥啊,现在这个世界上只有他可以解密这封密信了)。
为了演示解密过程,我们再举一个例子:
还是刚刚那个文件,命名为Hi.txt,这次我们用自己的公钥加密(这样我就可以用自己的私钥解密了):
显然这个生成的Hi.txt.gpg是二进制的,我们再生成一个ASCII的,名称默认为Hi.txt.asc:
对于这两个加密的文件(一个Hi.txt.gpg,一个Hi.txt.asc),分别对其进行解密,使用
均成功解密,显示了加密之前的信息。
此时,如果我们去解密刚刚用Justin的公钥加密过的文件Hello.txt.asc:
显然失败了,因为我们只有属于自己的私钥,不可能解开别的公钥加密过的文件。
现在我们再来考虑一下信任度的设置。之前由于我们未对Justin的公钥进行信任度设置,每次用到Justin的公钥的时候,gpg都会友善的提醒我们,在我们获取此公钥的时候,有可能公钥已经被篡改了,因此此公钥有可能不是Justin本人的。但是如果我们确信这就是Justin的公钥,我们可以对其设置信任度,使用
之后再查看公钥列表:
原来Justin的公钥之前显示的[未知]已经变成我们设置的[完全]了。我们可以发现我们自己的公钥被默认设置为绝对信任,这显然是必须的,也是肯定正确的。我们还可以发现修改完信任度之后再查询公钥时,gpg会先查询信任度数据库,这说明这些信任信息不是存在储存钥匙的文件里,而是存在另一个文件里的。
最后,我们说一下签名。
为避免别人宣称是你的风险,对所有你加密的东西签名是有用的。签名的意义在于两个方面:Authenticity和Integrity。即数字签名可以证明数据是你发送的,并同时证明发送的内容未曾被别人修改过。
签名的命令为
上面两条命令分别生成了Hi.txt.gpg和Hi.txt.asc两个文件。
需要注意的是,刚刚的签名自然是签的我们自己的名,所以用的是我们自己的私钥,需要用我们自己的公钥认证签名
两个文件均验证为正确,说明这两个文件是”刘海博“签的名。
用
签名后的文件,我们还可以使用解密来读取:
可以看到区别就在与verify只显示认证的结果,而decrypt同时也显示出了原数据的内容。
如果这个时候我们对认证后的动动手脚,修改一些内容:
可以看出签名的第二个功能生效了,我们可以根据签名验证文件内容是否被修改。
有趣的是,如果再把修改过后的内容修改回去,则认证又会再次通过。这也说明了签名的确就是对整个文件的内容进行Hash产生的。
而且,不管什么样的文件,签名的时候只是单纯的在文件内容前后添加头尾,即以下格式:
附录:为什么要先签名后加密?
答:
看你发送的这个信息算不算秘密。算的话必须先签名后加密。
如果不算的话都行。但签名后加密比较好。除非要大家都能验证信息来源。
对于这个问题我们举个例子:
对于先加密后签名
ABC
A要把秘密给B。
那么
A有A的签名私钥和B的加密公匙
B有A的签名公匙和B的加密私钥
现在C加入。欺骗B说他也知道这个秘密(其实他不知道)
C把自己的签名公匙给B
因为C知道A的签名公匙,C可以把A给B的信息签名去掉再加上自己的签名
这个时候
B有用自己公匙加密的2条信息。明文是一样的。一个A签名一个C签名。B是无法知道谁真正知道秘密。
如果是先签名后加密。
因为C不可能知道加密密匙,所以不能解密后改签名。所以就不能欺骗B说他也知道秘密。
所以先加密后签名的缺陷不是C能知道秘密,而是B可能被欺骗。
因此签名都用在义务宣言上,表明自己说过的负责,不会不认帐。大家不会没事去冒名。(比如欠条)
如果对于别人会冒名的宣言,比如(出售机密,勒索等)如果签名没有被加密,B就可能向不知道秘密的人买秘密。
要做到既加密又签名,完整的命令行大致如下:
gpg [-u Sender] [-r Recipient] [–armor] –sign –encrypt [Data]
-u (–local-user) -r (–recipient)
最后说一下密钥迁移的问题。
如果我们现在想换电脑,无疑我们需要把之前的公钥和自己的私钥全部都导出来。
我们将puppylpg的两个密钥导出成为两个文件,之后再导入另一个电脑。
注意导入私钥的时候需要添加
参阅:http://blog.csdn.net/puppylpg/article/details/50899484
公钥的作用:别人用来给你发加密的信息&别人验证你的签名
私钥的作用:你用来创建签名&解密别人发给你的信息的
具体而言,A要想发送加密信息到B,则:
A有A的签名私钥和B的加密公匙
B有A的签名公匙和B的加密私钥
使用GPG可以很好的演示这一点:
gpg (GnuPG) 2.1.11 libgcrypt 1.6.5 Copyright (C) 2016 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.
首先,我们在安装好GPG之后(安装步骤https://www.gnupg.org/howtos/zh/index.html),可以使用
gpg --gen-key生成属于我们自己的一对公钥和私钥。之后我们可以使用
gpg --export [UID]来输出UID所对应的公钥,比如对于我来说:
lgl@pArch ~ $ gpg --export -a 刘海博 -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v2 mQENBFbnwUkBCADtMQ73lZ1XEbcNbGyaF5IHQ1aoYBrIhj+BpXbV9Qz95OxqOoFP 6s0n1/cBhpjhhqm2hlJFhwrKIDMkTKBY0rif3ZHdHVKK7k7xW0qYWa0HZDtRApao N3lZ3Ay2EyTSPj6SoFxleLm8LoftlDscp90kK/zGiXf95pslTmk4ziSolOtPTvP7 FpSaYizOO3JfUKUDrTdXRcEx2p7KmXi8v1O33bY0YG6yRmff90DzMxYqQ2LUQBfl hVSu3mYKpP5IQ0tNgTCbUiyVqOX+TdxQoqMiTWiWvD5OJZf+7RqnbpQ9l6epmUEk HAJcvhcEfLeDslt2o+x2s7BXW1o71/Xa3Q/fABEBAAG0HuWImOa1t+WNmiA8c2hp bmluZ2xoYkAxNjMuY29tPokBNwQTAQgAIQUCVufBSQIbAwULCQgHAgYVCAkKCwIE FgIDAQIeAQIXgAAKCRBbDqAL2u3LWxkXB/96dBtELKkA6hc2BLBxLBxchakEeaMK lXDEiom6kwiqeI/H3KJchOtlTbBLGUmSdRAm3rX5UkVtaDvxW6iWuNzcbDZN6oCe YCFqOvmzLZ+YWh48tRBJOTEzrkZrT/OpTGRtRI0cAIAJ68rMc5Vpxl1Vqknp/BzI z84qPGBWgThy/UlgcFnbkZVLh37FLmIhtTMIbA1whum570/a/bnKP6xWnB4P5ryn 6lXLBMDMA2a0jtgzmywXm60nI6M77lzfd6UXGX0NQOU/AP+v0hNzkl4+KapEOONC x7MjoL09b946Tqysly5u6gJpK/YmD0UUnVrH2OW6YQy/UmXQk7mKjG/7uQENBFbn wUkBCACx3kvVDVjuo/LQrODb0wZig7NrsLasQ+dAOo/9UXY53wjrnLPiZLRbtYm1 tPFMykAv/23+vLXmLFW7gd0PjGOPZE4Q0/vR/Re+vJjonH3Z6E+DidE7T9vQmuB4 aLIvDpEcAWKSRN75/zLKzAysqHwEBXeSVD89bSMdH4rPpC70hABZZuVYC3rEkrdZ 6EcW7jca71eKVTKQRznuTZKzpHG8XwcgTt5qtmbZmWxIT4SMdxyI//fpAUjDc913 qN9i/ZY668g8URQLxCUTdFy04p1Vft1yCByZF9Pie5paVO28kgegZf1O6+k1rR42 WHbtLFq7xYgW3vOG9I9yQdA8oOUHABEBAAGJAR8EGAEIAAkFAlbnwUkCGwwACgkQ Ww6gC9rty1vt+ggAza5faR5AeHgIOnUyI3j28GxFey3E7CbVRO0ubO7Iq5qy+P1z EQPmnpeQ/FpDabvP4P7qds77U2wFbvsa/Ar4ZuznmNuL9r8fGJn6BrmPLAMxfwOo c+w6qN0iYp+kl6pRTYYolICyZfq/CLrDKxUaAHlSpZoEI5CUIs/tntcLJRSei/1S GUjXS7sqlVafNM2Vqxy3XBqVffXGsUNXr1zRGz/Dia9Kt3sztDYDjo3csHlEPVTw v1gRxVTnsrmoQlJ7+S2tT6hocuD5k6Ye11vyCMYny6BxCYz5CW6HtvAWs9kXT6E3 hTFS5THpkuu+uZLPM2CGJuFLdwNrBzMXHrqRaQ== =Eh6b -----END PGP PUBLIC KEY BLOCK-----
以上就是我的公钥,其中
-a是为了让字符以ASCII形式输出,而不是二进制。隐含地,结果将输出到标准输出(stdout)去,可以用
-o选项可以把它放到一个文件里去。
之后,我们需要得到别人的公钥,才能用他的公钥加密我们想要发给他的数据。
gpg --import [filename]即可导入别人的公钥,这个存放公钥的文件可以使用
-o选项导出。
我们可以通过
gpg --list-keys查看当前所有的公钥,比如:
lgl@pArch ~/tmp/GPGtest $ gpg --list-keys /home/lgl/.gnupg/pubring.kbx ---------------------------- pub rsa2048/DAEDCB5B 2016-03-15 [SC] uid [ 绝对 ] 刘海博 <shininglhb@163.com> sub rsa2048/7D6453AF 2016-03-15 [E] pub dsa1024/C9C40C31 2001-05-25 [SCA] uid [ 未知 ] Justin R. Miller <justin@solidlinux.com> uid [ 未知 ] Justin R. Miller <justin@voxel.net> sub elg1024/59FAB546 2001-05-25 [E]
说明我现在有两个公钥,一个是我自己的,另一个是Justin的。钥匙号分别为DAEDCB5B和C9C40C31,说到钥匙号,我们也可以使用别人的公钥钥匙号导入公钥
gpg --recv-keys 0xC9C40C31。
如果此时Justin用自己的私钥给文件签名(假设签名后的文件为sample.txt.asc,关于签名的内容我们会在最后再说)然后发给我,那么我就可以用公钥去验证文件签名的真伪:
lgl@pArch ~/tmp/GPGtest $ gpg --verify sample.txt.asc gpg: 于 Fri 17 Aug 2001 06:56:01 AM CST 创建的签名,使用 DSA,钥匙号 C9C40C31 gpg: 完好的签名,来自于“Justin R. Miller <justin@solidlinux.com>” [未知] gpg: 亦即“Justin R. Miller <justin@voxel.net>” [未知] gpg: 警告:这把密钥未经受信任的签名认证! gpg: 没有证据表明这个签名属于它所声称的持有者。 主钥指纹: 2231 DFF0 869E E3A5 885A E7D4 F787 7A2B C9C4 0C31
以上信息可以看出,我们使用Justin的公钥可以认证这个文件,且文件的内容未曾被更改。但是有警告信息,这些信息是在告诉我们:如果这把公钥真的是Justin的,那么这个文件就是Justin的,但是这把公钥的真伪并没有的到验证,可能存在我们当初得到的公钥是被别人替换过的公钥的情况。为此,我们应当跟Justin本人确认此公钥的正确性,如果确认无误,我们可以对这个公钥进行信任程度设置(稍后再讲信任度的设置)。
接下来看使用GPG加密与解密的过程:
首先,我们写一些话,想要发给Justin(Hello.txt):
Hello, I am Liu Haibo. This is my sample text sending to Justin.
既然我们想发给Justin,那么我们自然需要用Justin的公钥对其进行加密(然后Justin再用自己的私钥对我发过去的加密内容进行解密),加密使用到的命令是
gpg -e 要加密的文件名或者是
gpg --encrypt 要加密的文件名,我们可以再加
-r参数直接指定要发送的人的UID(即选用需要的公钥),如果此处不使用
-r,在执行加密的过程中也会要求填写接收人的UID:
lgl@pArch ~/tmp/GPGtest $ gpg -r justin -e Hello.txt gpg: 59FAB546:没有证据表明这把密钥真的属于它所声称的持有者 sub elg1024/59FAB546 2001-05-25 Justin R. Miller <justin@voxel.net> 主钥指纹: 2231 DFF0 869E E3A5 885A E7D4 F787 7A2B C9C4 0C31 子钥指纹: 5B6A 9C4D 7C54 5936 B9F5 4D8B EDD4 CD22 59FA B546 这把密钥并不一定属于用户标识声称的那个人。如果您真的知道自 己在做什么,您可以在下一个问题回答 yes。 无论如何还是使用这把密钥吗?(y/N)y
以上可以看出,虽然我们对内容进行了加密,但是由于我们还没有对公钥进行信任度设置,gpg仍在提醒我们公钥本身有可能就是假的。
接下来看看加密后的内容(Hello.txt.gpg):
lgl@pArch ~/tmp/GPGtest $ cat Hello.txt.gpg ����"Y��F�����re�5m�j ��� �▒�S�0��y���� �Z��Q�υ��a�$r�����p�su�����?��hd 5(7��,��S7_�WtN]��DGV��P�w��nKc�������>楖�,�Q8���Lխ4-v�7�6���▒�-�0��.����0K�Y��{��Ȟ��>o���`�^=��e~�C�(ȆY���W�%����Hy�I�dn�۴kv2HпA��8˰�����7����t�����.(��t�I��%
乱码,因为这是二进制文件。
试试在加密过程中加入
--armor参数(以ASCII而不是二进制输出):
lgl@pArch ~/tmp/GPGtest $ gpg -r justin -e --armor Hello.txt gpg: 59FAB546:没有证据表明这把密钥真的属于它所声称的持有者 sub elg1024/59FAB546 2001-05-25 Justin R. Miller <justin@voxel.net> 主钥指纹: 2231 DFF0 869E E3A5 885A E7D4 F787 7A2B C9C4 0C31 子钥指纹: 5B6A 9C4D 7C54 5936 B9F5 4D8B EDD4 CD22 59FA B546 这把密钥并不一定属于用户标识声称的那个人。如果您真的知道自 己在做什么,您可以在下一个问题回答 yes。 无论如何还是使用这把密钥吗?(y/N)y
接下来再查看加密后的文件(Hello.txt.asc):
lgl@pArch ~/tmp/GPGtest $ cat Hello.txt.asc -----BEGIN PGP MESSAGE----- Version: GnuPG v2 hQEOA+3UzSJZ+rVGEAP/YTDy4HcGP9PyvfKxH30fZtVJ/jqg/+NKJjTecuSdchSc RxDBwu0zEmpV0pdnllBteayfabPr1JDJdZ5UX6yCpsc/vON6nRVULGHSkACIXsmc m2vCTIMlbbnclu4bRSoXU5tI2tgWie6xFrZUMH7q4pRVUrL9wMYRyTUsP6wcJDYD /1ybF3IWEWjYiLWS+KDbiQUcvpLrJzXXNsiYsIUV4no1Uh14SOKraU3sz7zGq/Sy FuhdMALDENqVX2+tGhi9/u3qJq5NgSn1v+uUwJFqehYbO514LAxSczWSQGE7APUN vOPhLJURN7iHdN1cHnJvi2zvDHcvMssPwwPjUKtnnR3Z0oEBW8LuO7pICGZ5PDss 4ItACKwNQYPcNGukYvO+LuRbE7uxMegROeqpLPOjVNsNOiCQVHl4pI9KSV+WLFXl xgurX4Up1uUi1rW1mPZEaXbnMT+rcenY508Dj6ayYAN07XP5/wg5HDQF0S2+OIhW VQEkj6DiqZfbIEUSz2SDm5zIZiU= =IMgg -----END PGP MESSAGE-----
虽然是字符,但显然内容已经被加密了,无法看懂。
我们把加密后的信息发给Justin之后,他直接用自己的私钥解密就可以阅读我们想给他传达的信息了(但是我无法演示解密过程,因为我没有Justin的私钥啊,现在这个世界上只有他可以解密这封密信了)。
为了演示解密过程,我们再举一个例子:
还是刚刚那个文件,命名为Hi.txt,这次我们用自己的公钥加密(这样我就可以用自己的私钥解密了):
lgl@pArch ~/tmp/GPGtest $ gpg -r 刘海博 -e Hi.txt lgl@pArch ~/tmp/GPGtest $ cat Hi.txt.gpg � �]�}dS��3��+�8ŧ�&,v�NZ_��[��iC��8�n$ÿ�&V�{��9��B�~g�?g�uU����|'euQ~Pk��$Qp�D����G�MrӨr&8▒�u�MJ'�Gv���Μ�H▒j6�9YM�H�P �N������N��J���|]��r(��c���IÁ���@ŧ���b���RTFOWx�9�▒EC����6M�js3�Oߋs��:��f.=5��[i͕����1 ���Y>��a�����NT*�(��V?▒҂�"�M ��P�{�g����$�v�▒R8 콗����Ƈ�����-�b��Z�.X~�4�Ղ�g[X�[g m�`����5��#MU\���˧4%
显然这个生成的Hi.txt.gpg是二进制的,我们再生成一个ASCII的,名称默认为Hi.txt.asc:
lgl@pArch ~/tmp/GPGtest $ gpg -r 刘海博 -e --armor Hi.txt lgl@pArch ~/tmp/GPGtest $ cat Hi.txt.asc -----BEGIN PGP MESSAGE----- Version: GnuPG v2 hQEMA9RdjQJ9ZFOvAQgAhZ0OTp/AVjE+8eLxFUt5W4UM1ZbsiJ0KMB8gAPm+5Lqx ewOGtRXN2jWkRIuYXi0UKQmv/uTOUXQFDGpmeBtm2dkX+TV54GCdrarxq32soZzk Kxbvj0ucpiSP/EUsWtNacuThhzgiibxGZq6LlD71t6UZhVC8MtQ7AOi1yeh9cZV9 KCJLH8a81yU6hL+uk8OnOn6RJW6jMaITNpN36k4kbwLbrYAzSkD/m9zEatVE/Jpm ozYyV9NznAETLZ3i+RcmTAMzP4Ka1R9luwSvNKdHbdEq/jboJZaS2Ye+JLfW38ID 4P00Z91U0JoM64lqVlskzH2zIfZJpj+uLJiskQDw+NKCAbanCIfDqAn/2LYlDoMI oHRI6Qq58OSYj4iw2OVmzUYQQVLg0s4RsrMKHtLRWc8KR5wcw8pWxD0gdQrTqUEi tvv9y2c3afhn7AQzDvtIxrQIt/7MS37e4A6Y6f9Ax43rWLmL0198tRuojrwpk6UR uTF5oyUpJx2VFYUDtVh2JKCzjQ== =zvVm -----END PGP MESSAGE-----
对于这两个加密的文件(一个Hi.txt.gpg,一个Hi.txt.asc),分别对其进行解密,使用
gpg -d 密文文件名或者
gpg --decrypt 密文文件名:
lgl@pArch ~/tmp/GPGtest $ gpg -d Hi.txt.asc
gpg: 由 2048 位的 RSA 密钥加密,钥匙号为 7D6453AF、生成于 2016-03-15
“刘海博 <shininglhb@163.com>”
Hello, I am Liu Haibo.
This is my sample text sending to Justin.
lgl@pArch ~/tmp/GPGtest $ gpg -d Hi.txt.gpg
gpg: 由 2048 位的 RSA 密钥加密,钥匙号为 7D6453AF、生成于 2016-03-15
“刘海博 <shininglhb@163.com>”
Hello, I am Liu Haibo. This is my sample text sending to Justin.
均成功解密,显示了加密之前的信息。
此时,如果我们去解密刚刚用Justin的公钥加密过的文件Hello.txt.asc:
lgl@pArch ~/tmp/GPGtest $ gpg -d Hello.txt.asc gpg: 由 1024 位的 ELG 密钥加密,钥匙号为 59FAB546、生成于 2001-05-25 “Justin R. Miller <justin@solidlinux.com>” gpg: 解密失败:没有秘匙
显然失败了,因为我们只有属于自己的私钥,不可能解开别的公钥加密过的文件。
现在我们再来考虑一下信任度的设置。之前由于我们未对Justin的公钥进行信任度设置,每次用到Justin的公钥的时候,gpg都会友善的提醒我们,在我们获取此公钥的时候,有可能公钥已经被篡改了,因此此公钥有可能不是Justin本人的。但是如果我们确信这就是Justin的公钥,我们可以对其设置信任度,使用
gpg --edit-key:
lgl@pArch ~/tmp/GPGtest $ gpg --edit-key justin@solidlinux.com gpg (GnuPG) 2.1.11; Copyright (C) 2016 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. pub dsa1024/C9C40C31 创建于:2001-05-25 有效至:永不过期 可用于:SCA 信任度:未知 有效性:未知 sub elg1024/59FAB546 创建于:2001-05-25 有效至:永不过期 可用于:E [ 未知 ] (1). Justin R. Miller <justin@solidlinux.com> [ 未知 ] (2) Justin R. Miller <justin@voxel.net> gpg> sign Really sign all text user IDs? (y/N) y pub dsa1024/C9C40C31 创建于:2001-05-25 有效至:永不过期 可用于:SCA 信任度:未知 有效性:未知 主钥指纹: 2231 DFF0 869E E3A5 885A E7D4 F787 7A2B C9C4 0C31 Justin R. Miller <justin@solidlinux.com> Justin R. Miller <justin@voxel.net> 您真的确定要签名这把密钥,使用您的密钥 “刘海博 <shininglhb@163.com>”(DAEDCB5B) 真的要签名吗?(y/N)y gpg> trust pub dsa1024/C9C40C31 创建于:2001-05-25 有效至:永不过期 可用于:SCA 信任度:未知 有效性:未知 sub elg1024/59FAB546 创建于:2001-05-25 有效至:永不过期 可用于:E [ 未知 ] (1). Justin R. Miller <justin@solidlinux.com> [ 未知 ] (2) Justin R. Miller <justin@voxel.net> 您是否相信这位用户有能力验证其他用户密钥的有效性(查对身份证、通过不同的渠道检查 指纹等)? 1 = 我不知道或我不作答 2 = 我不相信 3 = 我勉强相信 4 = 我完全相信 5 = 我绝对相信 m = 回到主菜单 您的决定是什么?5 您真的要把这把密钥设成绝对信任?(y/N)n 您的决定是什么?4 pub dsa1024/C9C40C31 创建于:2001-05-25 有效至:永不过期 可用于:SCA 信任度:完全 有效性:未知 sub elg1024/59FAB546 创建于:2001-05-25 有效至:永不过期 可用于:E [ 未知 ] (1). Justin R. Miller <justin@solidlinux.com> [ 未知 ] (2) Justin R. Miller <justin@voxel.net> 请注意,在您重启程序之前,显示的密钥有效性未必正确, gpg> 要保存变动吗?(y/N)y
之后再查看公钥列表:
lgl@pArch ~/tmp/GPGtest $ gpg --list-keys gpg: 正在检查信任度数据库 gpg: marginals needed: 3 completes needed: 1 trust model: PGP gpg: 深度:0 有效性: 1 已签名: 1 信任度:0-,0q,0n,0m,0f,1u gpg: 深度:1 有效性: 1 已签名: 0 信任度:0-,0q,0n,0m,1f,0u /home/lgl/.gnupg/pubring.kbx ---------------------------- pub rsa2048/DAEDCB5B 2016-03-15 [SC] uid [ 绝对 ] 刘海博 <shininglhb@163.com> sub rsa2048/7D6453AF 2016-03-15 [E] pub dsa1024/C9C40C31 2001-05-25 [SCA] uid [ 完全 ] Justin R. Miller <justin@solidlinux.com> uid [ 完全 ] Justin R. Miller <justin@voxel.net> sub elg1024/59FAB546 2001-05-25 [E]
原来Justin的公钥之前显示的[未知]已经变成我们设置的[完全]了。我们可以发现我们自己的公钥被默认设置为绝对信任,这显然是必须的,也是肯定正确的。我们还可以发现修改完信任度之后再查询公钥时,gpg会先查询信任度数据库,这说明这些信任信息不是存在储存钥匙的文件里,而是存在另一个文件里的。
最后,我们说一下签名。
为避免别人宣称是你的风险,对所有你加密的东西签名是有用的。签名的意义在于两个方面:Authenticity和Integrity。即数字签名可以证明数据是你发送的,并同时证明发送的内容未曾被别人修改过。
签名的命令为
gpg -s [Data]或者
gpg --sign [Data]。这样做的时候,同时数据也被压缩。也就是说,最终结果是无法直接读懂的。若你想要一个能直接读懂的结果,你可以用
gpg --clearsign [Data],这样就能保证结果是清晰可读的。同时它也照样对数据签名:
lgl@pArch ~/tmp/minecraft $ gpg -s Hi.txt lgl@pArch ~/tmp/minecraft $ gpg --clearsign Hi.txt
上面两条命令分别生成了Hi.txt.gpg和Hi.txt.asc两个文件。
需要注意的是,刚刚的签名自然是签的我们自己的名,所以用的是我们自己的私钥,需要用我们自己的公钥认证签名
gpg --verify 签名文件:
lgl@pArch ~/tmp/minecraft $ gpg --verify Hi.txt.asc gpg: 于 Wed 16 Mar 2016 02:33:42 AM CST 创建的签名,使用 RSA,钥匙号 DAEDCB5B gpg: 完好的签名,来自于“刘海博 <shininglhb@163.com>” [绝对] lgl@pArch ~/tmp/minecraft $ gpg --verify Hi.txt.gpg gpg: 于 Wed 16 Mar 2016 02:33:18 AM CST 创建的签名,使用 RSA,钥匙号 DAEDCB5B gpg: 完好的签名,来自于“刘海博 <shininglhb@163.com>” [绝对]
两个文件均验证为正确,说明这两个文件是”刘海博“签的名。
用
gpg -b (--detach-sign) [Data],我们还可以将签名写进另一个文件。
签名后的文件,我们还可以使用解密来读取:
lgl@pArch ~/tmp/minecraft $ gpg -d Hi.txt.asc Hello, I am Liu Haibo. This is my sample text sending to Justin. gpg: 于 Wed 16 Mar 2016 02:33:42 AM CST 创建的签名,使用 RSA,钥匙号 DAEDCB5B gpg: 完好的签名,来自于“刘海博 <shininglhb@163.com>” [绝对]
可以看到区别就在与verify只显示认证的结果,而decrypt同时也显示出了原数据的内容。
如果这个时候我们对认证后的动动手脚,修改一些内容:
lgl@pArch ~/tmp/minecraft $ gpg --verify Hi.txt.asc gpg: 于 Wed 16 Mar 2016 02:33:42 AM CST 创建的签名,使用 RSA,钥匙号 DAEDCB5B gpg: 已损坏的签名,来自于“刘海博 <shininglhb@163.com>” [绝对] lgl@pArch ~/tmp/minecraft $ gpg -d Hi.txt.asc Hello, I am Liu Haibdddddo. This is my sample text sending to Justin. gpg: 于 Wed 16 Mar 2016 02:33:42 AM CST 创建的签名,使用 RSA,钥匙号 DAEDCB5B gpg: 已损坏的签名,来自于“刘海博 <shininglhb@163.com>” [绝对]
可以看出签名的第二个功能生效了,我们可以根据签名验证文件内容是否被修改。
有趣的是,如果再把修改过后的内容修改回去,则认证又会再次通过。这也说明了签名的确就是对整个文件的内容进行Hash产生的。
而且,不管什么样的文件,签名的时候只是单纯的在文件内容前后添加头尾,即以下格式:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 //此处为原文件内容 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2 //此处为一堆码 -----END PGP SIGNATURE-----
附录:为什么要先签名后加密?
答:
看你发送的这个信息算不算秘密。算的话必须先签名后加密。
如果不算的话都行。但签名后加密比较好。除非要大家都能验证信息来源。
对于这个问题我们举个例子:
对于先加密后签名
ABC
A要把秘密给B。
那么
A有A的签名私钥和B的加密公匙
B有A的签名公匙和B的加密私钥
现在C加入。欺骗B说他也知道这个秘密(其实他不知道)
C把自己的签名公匙给B
因为C知道A的签名公匙,C可以把A给B的信息签名去掉再加上自己的签名
这个时候
B有用自己公匙加密的2条信息。明文是一样的。一个A签名一个C签名。B是无法知道谁真正知道秘密。
如果是先签名后加密。
因为C不可能知道加密密匙,所以不能解密后改签名。所以就不能欺骗B说他也知道秘密。
所以先加密后签名的缺陷不是C能知道秘密,而是B可能被欺骗。
因此签名都用在义务宣言上,表明自己说过的负责,不会不认帐。大家不会没事去冒名。(比如欠条)
如果对于别人会冒名的宣言,比如(出售机密,勒索等)如果签名没有被加密,B就可能向不知道秘密的人买秘密。
要做到既加密又签名,完整的命令行大致如下:
gpg [-u Sender] [-r Recipient] [–armor] –sign –encrypt [Data]
-u (–local-user) -r (–recipient)
最后说一下密钥迁移的问题。
如果我们现在想换电脑,无疑我们需要把之前的公钥和自己的私钥全部都导出来。
gpg --export puppylpg > puppylpg.public gpg --export-secret-key puppylpg > puppylpg.private
我们将puppylpg的两个密钥导出成为两个文件,之后再导入另一个电脑。
gpg --import puppylpg.public gpg --allow-secret-key-import --import puppylpg.private
注意导入私钥的时候需要添加
--allow-secret-key-import给予允许添加私钥的权限,并且也不能遗漏
--import参数。
参阅:http://blog.csdn.net/puppylpg/article/details/50899484
相关文章推荐
- 用ASP编写的加密和解密类
- 解密网页加密的两个方法
- C#创建自签名认证文件的方法
- VBS脚本加密/解密VBS脚本(简易免杀版1.1)
- BAT加密工具 EncryBat 非编译型bat批处理加密方案与代码
- C#对称加密(AES加密)每次生成的结果都不同的实现思路和代码实例
- SQLServer 2008中的代码安全(一) 存储过程加密与安全上下文
- 实例讲解SQL Server加密功能
- C#编写DES加密、解密类
- C#实现对文件进行加密解密的方法
- C#实现数据包加密与解密实例详解
- C#最简单的字符串加密解密方法
- C#加密app.config中连接字符串的方法
- C#使用伪随机数实现加密用户密码的方法
- asp MD5加密方式使用建议
- 利用Gpg4win来打造一个安全的加密文件
- WinSrv 2003系统加固教程
- .NET实现一机一码加密、把EXE变成图片运行,被破解自动销毁随时授权回收
- 域环境批量推送OUTLOOK签名