使用GPG學習非對稱加密

  非對稱加密需要公鑰和私鑰:

你的公鑰的作用:別人用來給你發加密的信息&別人驗證你的簽名,即加密&驗證(別人來做)
你的私鑰的作用:你用來創建簽名&解密別人發給你的信息的,即解密&簽名(你來做)

  具體而言,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         [ 絕對 ] 劉海博 <[email protected]>
sub   rsa2048/7D6453AF 2016-03-15 [E]

pub   dsa1024/C9C40C31 2001-05-25 [SCA]
uid         [ 未知 ] Justin R. Miller <[email protected]>
uid         [ 未知 ] Justin R. Miller <[email protected]>
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�HPN������N��J���|]��r(��c���IÁ���@ŧ���b���RTFOWx9�▒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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章