我們平時都聽過非對稱加密抬探,公鑰和私鑰,簽名驗證衣吠,但這些證書都是怎么得到的呢茶敏?本篇文章會解答這些問題。
背景介紹
加密的一個簡單但又實用的任務就是發(fā)送加密電子郵件缚俏。多年來惊搏,為電子郵件進行加密的標準一直是PGP(Pretty Good Privacy)。程序員Phil Zimmermann特別為電子郵件的保密編寫的PGP忧换。
這個軟件非常好用恬惯,迅速流傳開來,成了許多程序員的必備工具亚茬。但是,它是商業(yè)軟件碗暗,不能自由使用洲守。
作為PGP的替代,如今已經有一個開放源代碼的類似產品可供使用。GPG(Gnu Privacy Guard),它不包含專利算法,能夠無限制的用于商業(yè)應用。
本文將會介紹文件加密什黑,至于GPG的其他用途,比如郵件加密圣絮,請參考這個網站https://help.ubuntu.com
安裝
本人使用mac電腦棒搜,因此使用brew安裝的闺鲸,很簡單赤屋,打開終端立镶,輸入brew install gpg
就行了,至于其他的平臺类早,可以自行搜索媚媒。
bogon:~ XXXX$ brew install gpg
==> Downloading https://homebrew.bintray.com/bottles/gnupg-1.4.20.el_capitan.bot
######################################################################## 100.0%
==> Pouring gnupg-1.4.20.el_capitan.bottle.tar.gz
?? /usr/local/Cellar/gnupg/1.4.20: 53 files, 5.4M
安裝完成后,鍵入命令gpg --help
:
bogon:~ XXXX$ gpg --help
gpg (GnuPG) 1.4.20
Copyright (C) 2015 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.
Home: ~/.gnupg
支持的算法:
公鑰:RSA, RSA-E, RSA-S, ELG-E, DSA
對稱加密:IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256,
TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256
散列:MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
壓縮:不壓縮, ZIP, ZLIB, BZIP2
語法:gpg [選項] [文件名]
簽名莺奔、檢查欣范、加密或解密
默認的操作依輸入數(shù)據而定
指令:
-s, --sign [文件名] 生成一份簽名
--clearsign [文件名] 生成一份明文簽名
-b, --detach-sign 生成一份分離的簽名
-e, --encrypt 加密數(shù)據
-c, --symmetric 僅使用對稱加密
-d, --decrypt 解密數(shù)據(默認)
--verify 驗證簽名
--list-keys 列出密鑰
--list-sigs 列出密鑰和簽名
--check-sigs 列出并檢查密鑰簽名
--fingerprint 列出密鑰和指紋
-K, --list-secret-keys 列出私鑰
--gen-key 生成一副新的密鑰對
--delete-keys 從公鑰鑰匙環(huán)里刪除密鑰
--delete-secret-keys 從私鑰鑰匙環(huán)里刪除密鑰
--sign-key 為某把密鑰添加簽名
--lsign-key 為某把密鑰添加本地簽名
--edit-key 編輯某把密鑰或為其添加簽名
--gen-revoke 生成一份吊銷證書
--export 導出密鑰
--send-keys 把密鑰導出到某個公鑰服務器上
--recv-keys 從公鑰服務器上導入密鑰
--search-keys 在公鑰服務器上搜尋密鑰
--refresh-keys 從公鑰服務器更新所有的本地密鑰
--import 導入/合并密鑰
--card-status 打印智能卡狀態(tài)
--card-edit 更改智能卡上的數(shù)據
--change-pin 更改智能卡的 PIN
--update-trustdb 更新信任度數(shù)據庫
--print-md 算法 [文件]
使用指定的散列算法打印報文散列值
選項:
-a, --armor 輸出經 ASCII 封裝
-r, --recipient 某甲 為收件者“某甲”加密
-u, --local-user 使用這個用戶標識來簽名或解密
-z N 設定壓縮等級為 N (0 表示不壓縮)
--textmode 使用標準的文本模式
-o, --output 指定輸出文件
-v, --verbose 詳細模式
-n, --dry-run 不做任何改變
-i, --interactive 覆蓋前先詢問
--openpgp 行為嚴格遵循 OpenPGP 定義
--pgp2 生成與 PGP 2.x 兼容的報文
(請參考在線說明以獲得所有命令和選項的完整清單)
范例:
-se -r Bob [文件名] 為 Bob 這個收件人簽名及加密
--clearsign [文件名] 做出明文簽名
--detach-sign [文件名] 做出分離式簽名
--list-keys [某甲] 顯示密鑰
--fingerprint [某甲] 顯示指紋
請向 <gnupg-bugs@gnu.org> 報告程序缺陷。
請向 <i18n-zh@googlegroups.com> 反映簡體中文翻譯的問題令哟。
這些幫助信息非常有用恼琼,下邊演示的很多功能也是基于上邊這些參數(shù)的。這里把他們列出來屏富,方便在使用的時候查詢晴竞。
如果能夠顯示上邊的信息,說明GPG安裝成功了
生成密鑰
利用上邊的幫助信息中--gen-key 生成一副新的密鑰對
可以生成密鑰狠半。
安裝成功后噩死,使用gen-ken參數(shù)生成自己的密鑰。在終端中輸入:
gpg --gen-key
回車后神年,會看到:
gpg (GnuPG) 1.4.20; Copyright (C) 2015 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.
gpg: 已創(chuàng)建目錄‘/Users/machao/.gnupg’
gpg: 新的配置文件‘/Users/machao/.gnupg/gpg.conf’已建立
gpg: 警告:在‘/Users/machao/.gnupg/gpg.conf’里的選項于此次運行期間未被使用
gpg: 鑰匙環(huán)‘/Users/machao/.gnupg/secring.gpg’已建立
gpg: 鑰匙環(huán)‘/Users/machao/.gnupg/pubring.gpg’已建立
請選擇您要使用的密鑰種類:
(1) RSA and RSA (default)
(2) DSA and Elgamal
(3) DSA (僅用于簽名)
(4) RSA (僅用于簽名)
您的選擇已维?
第一段是版權聲明,然后讓用戶自己選擇加密算法已日。默認選擇第一個選項垛耳,表示加密和簽名都使用RSA算法。我們輸入1
,然后回車
RSA 密鑰長度應在 1024 位與 4096 位之間。
您想要用多大的密鑰尺寸堂鲜?
這一步要讓我們輸入密鑰長度栈雳,長度越長越安全,默認為2048。我們輸入2048
回車
您所要求的密鑰尺寸是 2048 位
請設定這把密鑰的有效期限缔莲。
0 = 密鑰永不過期
<n> = 密鑰在 n 天后過期
<n>w = 密鑰在 n 周后過期
<n>m = 密鑰在 n 月后過期
<n>y = 密鑰在 n 年后過期
密鑰的有效期限是哥纫?(0)
如果密鑰只是個人使用,并且你很確定可以有效保管私鑰痴奏,建議選擇第一個選項蛀骇,即永不過期。注意抛虫,如果想設置在2年后過期松靡,那么應該輸入2y
,然后回車 回答完上面三個問題以后,系統(tǒng)讓你確認建椰。
密鑰于 日 10/ 8 11:20:32 2017 CST 過期
以上正確嗎雕欺?(y/n)y
到這里,我們對要生成的密鑰的配置已經完成了棉姐,然后我們還需要一個標識屠列,
您需要一個用戶標識來辨識您的密鑰;本軟件會用真實姓名伞矩、注釋和電子郵件地址組合
成用戶標識笛洛,如下所示:
“Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>”
按照要求依次輸入就行了
真實姓名:
電子郵件地址:
注釋:
我們這里假設輸入的信息為:
真實姓名:Zhang San
電子郵件地址:zhangsan@163.com
注釋:
回車后:
您選定了這個用戶標識:
“Zhang San <zhangsan@163.com>”
更改姓名(N)、注釋(C)乃坤、電子郵件地址(E)或確定(O)/退出(Q)苛让?
我們輸入o
,回車后
您需要一個密碼來保護您的私鑰。
然后輸入密碼湿诊,再次確認密碼后狱杰,
我們需要生成大量的隨機字節(jié)。這個時候您可以多做些瑣事(像是敲打鍵盤厅须、移動
鼠標仿畸、讀寫硬盤之類的),這會讓隨機數(shù)字發(fā)生器有更好的機會獲得足夠的熵數(shù)朗和。
.+++++
...+++++
我們需要生成大量的隨機字節(jié)错沽。這個時候您可以多做些瑣事(像是敲打鍵盤、移動
鼠標眶拉、讀寫硬盤之類的)千埃,這會讓隨機數(shù)字發(fā)生器有更好的機會獲得足夠的熵數(shù)。
....................+++++
...........+++++
gpg: /Users/XXXX/.gnupg/trustdb.gpg:建立了信任度數(shù)據庫
gpg: 密鑰 74A64469 被標記為絕對信任
公鑰和私鑰已經生成并經簽名忆植。
gpg: 正在檢查信任度數(shù)據庫
gpg: 需要 3 份勉強信任和 1 份完全信任镰禾,PGP 信任模型
gpg: 深度:0 有效性: 1 已簽名: 0 信任度:0-皿曲,0q唱逢,0n吴侦,0m,0f坞古,1u
gpg: 下次信任度數(shù)據庫檢查將于 2017-10-08 進行
pub 2048R/74A64469 2016-10-08 [有效至:2017-10-08]
密鑰指紋 = 2187 78CA 2E78 83C2 039C E47B D94A 622A 74A6 5569
uid Zhang San <zhangsan@163.com>
sub 2048R/490E5BC8 2016-10-08 [有效至:2017-10-08]
請注意上面的字符串"74A64469"备韧,這是"用戶ID"的Hash字符串,可以用來替代"用戶ID"痪枫。到此為止织堂,我們已經完成了生成公鑰和私鑰的任務了,文件在/Users/XXXX/.gnupg/pubring.gpg
。
這時奶陈,最好再生成一張"撤銷證書"易阳,以備以后密鑰作廢時,可以請求外部的公鑰服務器撤銷你的公鑰吃粒。
gpg --gen-revoke 74A64469
然后按照下邊的步驟依次執(zhí)行就行了
sec 2048R/74A64469 2016-10-08 Zhang San <zhangsan@163.com>
要為這把密鑰建立一份吊銷證書嗎潦俺?(y/N)y
請選擇吊銷的原因:
0 = 未指定原因
1 = 密鑰已泄漏
2 = 密鑰被替換
3 = 密鑰不再使用
Q = 取消
(也許您會想要在這里選擇 1)
您的決定是什么?0
請輸入描述(可選)徐勃;以空白行結束:
>
吊銷原因:未指定原因
(不給定描述)
這樣可以嗎事示? (y/N)y
您需要輸入密碼,才能解開這個用戶的私鑰:“Zhang San <zhangsan@163.com>”
2048 位的 RSA 密鑰僻肖,鑰匙號 74A64469肖爵,建立于 2016-10-08
已強行使用 ASCII 封裝過的輸出。
已建立吊銷證書臀脏。
請把這個文件轉移到一個可隱藏起來的介質(如軟盤)上劝堪;如果壞人能夠取得這
份證書的話,那么他就能讓您的密鑰無法繼續(xù)使用揉稚。把這份憑證打印出來再藏
到安全的地方也是很好的方法秒啦,以免您的保存媒體損毀而無法讀取。但是千萬
小心:您的機器上的打印系統(tǒng)可能會在打印過程中把這些數(shù)據臨時在某個其他
人也能夠看得到的地方窃植!
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
Comment: A revocation certificate should follow
iQEfBCABAgAJBQJX+GqQAh0AAAoJENlKYip0plVp0q8H/jDfnm8ElhgN+5dgn7uu
wrbgDMBrtFzuxqGPPlTTJLHprUQUuQBG3uMPjQCCh52fMY8DUAjlcsAcynpMYLll
2mdHPdWC7SDK/qPhZ2AGO+iJ333I3Ir4vYfjEdNetyD6ZfBpk7m1rqz3BYtBey5N
6FSrLXyaNu88ftwozqxBqRZE2b09boafX5y/UrgHpco13a8DdredSN49D0d3EwxZ
e78reDEpE4kwh4E0xAEXnX4ILDCSnTz4S8wGFV8uddB4Snyh8m+HiuDlp7h9kYw+
c5BMSgSG/DxFAdIpetfdMMVtsAMTTy+nfMvIXWNFjARSEErW5Fz0TqkFhyT3Ntxu
glE=
=ee65
-----END PGP PUBLIC KEY BLOCK-----
查看密鑰列表
list-keys參數(shù)列出系統(tǒng)中已有的密鑰
gpg --list-keys
回車后:
/Users/XXXX/.gnupg/pubring.gpg
--------------------------------
pub 2048R/74A64469 2016-10-08 [有效至:2017-10-08]
uid Zhang San <zhangsan@163.com>
sub 2048R/490E5BC8 2016-10-08 [有效至:2017-10-08]
第一行顯示公鑰文件名(pubring.gpg)帝蒿,第二行顯示公鑰特征(4096位,Hash字符串和生成時間)巷怜,第三行顯示"用戶ID"葛超,第四行顯示私鑰特征。
如果你要從密鑰列表中刪除某個密鑰延塑,可以使用delete-key參數(shù)绣张。
gpg --delete-key [用戶ID]
輸出密鑰
公鑰文件(.gnupg/pubring.gpg)以二進制形式儲存,armor參數(shù)可以將其轉換為ASCII碼顯示关带。
gpg --armor --output public-key.txt --export [用戶ID]
"用戶ID"指定哪個用戶的公鑰侥涵,output參數(shù)指定輸出文件名(public-key.txt)沼撕。
類似地,export-secret-keys參數(shù)可以轉換私鑰芜飘。
gpg --armor --output private-key.txt --export-secret-keys
打開public-key.txt
private-key.txt
就能看到公鑰和私鑰了务豺。
上傳公鑰
公鑰服務器是網絡上專門儲存用戶公鑰的服務器。send-keys參數(shù)可以將公鑰上傳到服務器
gpg --send-keys [用戶ID] --keyserver hkp://subkeys.pgp.net
使用上面的命令嗦明,你的公鑰就被傳到了服務器subkeys.pgp.net笼沥,然后通過交換機制,所有的公鑰服務器最終都會包含你的公鑰娶牌。
由于公鑰服務器沒有檢查機制奔浅,任何人都可以用你的名義上傳公鑰,所以沒有辦法保證服務器上的公鑰的可靠性诗良。通常汹桦,你可以在網站上公布一個公鑰指紋,讓其他人核對下載到的公鑰是否為真鉴裹。fingerprint參數(shù)生成公鑰指紋舞骆。
gpg --fingerprint [用戶ID]
輸入密鑰
除了生成自己的密鑰,還需要將他人的公鑰或者你的其他密鑰輸入系統(tǒng)壹罚。這時可以使用import參數(shù)葛作。
gpg --import [密鑰文件]
為了獲得他人的公鑰,可以讓對方直接發(fā)給你猖凛,或者到公鑰服務器上尋找赂蠢。
gpg --keyserver hkp://subkeys.pgp.net --search-keys [用戶ID]
正如前面提到的,我們無法保證服務器上的公鑰是否可靠辨泳,下載后還需要用其他機制驗證.
加密和解密
我們演示加密和解密的過程虱岂,這個過程是對文件進行的。假如我們有一個test.txt
文件菠红。這個文件中的內容為:
張飛第岖,我愛你,今晚約嗎试溯?
床前明月光蔑滓,疑是地上霜朦佩。
舉頭望明月巢块,低頭思故鄉(xiāng)。
encrypt參數(shù)用于加密浑厚。我們使用下邊的命令對這個文件進行加密摹闽。
gpg --recipient 74A64469 --output test_en.txt --encrypt test.txt
然后我們在test.txt
的同一目錄下得到了test_en.txt
蹄咖。我們打開后可以看到加密后的數(shù)據為:
8501 0c03 50c4 def5 490e 5bc8 0107 f901
58c7 1221 33ee cc6c 4b43 8d5d a1f5 1a14
a5ac d406 7f24 a6bf 342c 3ba1 6f95 6d1b
8aae c45a 9a25 dece 7973 f5e0 44a0 7d43
7701 bd7b 02cc 3287 b65e 5915 3a67 2046
2d96 42c0 98fa d468 3187 f340 674a 772c
a280 7ab9 73d1 5feb 28c7 bc64 f102 e978
0ca5 ff7e ff1f a0f8 ba6a ea43 cc68 cf15
acff dfe9 fba3 7576 5c78 fc4a 8ed6 232b
6313 8246 ee38 70c2 1b0c 46fb 2064 662e
2977 79a7 64d8 81dd e55f 5b77 edb8 0a0c
caa0 9df0 4db2 a1e5 fe5f e16f 7be5 03b4
f741 d1a9 e429 d909 b94b a539 b0cc cc08
70b7 8d1f 4212 ba89 00ed fce4 ba97 6b51
8546 8bfa 1129 9862 d779 0382 bab0 ae0f
4855 bf75 82bf 743d 6b9e 4072 b47f 551d
143a 9355 67b9 dc7a 1511 4d0d 79bc d8d2
b001 f69c af7c 5cd2 6f2c 7d68 8ebc 80d8
07fb d120 fd2b 4a76 774c 8b82 e5e3 3414
de28 f947 16ff be94 ee01 ae40 8deb 6786
bf4f c602 5efb 8ae0 55f6 6cc2 55dc a6de
a8e0 0239 7de4 43b5 3344 f5fb 5e8d 9e26
0961 ddae 4f57 be79 6a1b b7fd 1f0b d510
e7ad 9c0c cc7e c75f 06d1 4da7 2ae5 a7d2
02b6 d93c 729b bf94 31dd a627 1423 1f08
db2b e6a3 a9f2 8165 bc16 8641 3430 dbaf
0885 4df6 e5cc f542 d3e6 60e2 91ae c0e7
69d7 8507 9d54 c25d 3a3d 4e63 79dd 8eaf
84
哈哈,如果給你一串這玩意付鹿,誰能看懂澜汤? 這也就是為什么編譯別的軟件的文件的時候顯示這內容了蚜迅,都是進行加密過的文件,只有進行解密后才能讀出數(shù)據俊抵。
recipient參數(shù)指定接收者的公鑰谁不,output參數(shù)指定加密后的文件名,encrypt參數(shù)指定源文件务蝠。運行上面的命令后拍谐,test_en.txt
就是已加密的文件,可以把它發(fā)給對方馏段。
使用下邊的命令進行解密
gpg test_en.txt
依次完成下邊的命令:
bogon:Desktop XXXX$ gpg test_en.txt
您需要輸入密碼,才能解開這個用戶的私鑰:“Zhang San <zhangsan@163.com>”
2048 位的 RSA 密鑰践瓷,鑰匙號 490E5BC8院喜,建立于 2016-10-08 (主鑰匙號 74A64469)
gpg: 由 2048 位的 RSA 密鑰加密,鑰匙號為 490E5BC8晕翠、生成于 2016-10-08
“Zhang San <zhangsan@163.com>”
gpg: test_en.txt:未知的后綴名
請輸入新的文件名 [test.txt]: test2.txt
然后在test2.txt
中就看到了解密后的數(shù)據喷舀。
簽名
有時,我們不需要加密文件淋肾,只需要對文件簽名硫麻,表示這個文件確實是我本人發(fā)出的。sign參數(shù)用來簽名樊卓。
gpg --sign test.txt
然后生成了一個test.txt.gpg
文件拿愧,我們打開這個文件后,發(fā)現(xiàn)這也是一個二進制的數(shù)據碌尔,這并不是加密后的數(shù)據浇辜,與上邊的二進制數(shù)據不一樣。如果想生成ASCII碼的簽名文件唾戚,可以使用clearsign參數(shù)
gpg --clearsign test.txt
然后生成了一個test.txt.asc
文件柳洋,打開后可以看出:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
張飛,我愛你叹坦,今晚約嗎熊镣?
床前明月光,疑是地上霜募书。
舉頭望明月绪囱,低頭思故鄉(xiāng)。
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAEBAgAGBQJX+Jl5AAoJENlKYip0plVpDIMIAJscuAXq/+g+kBVqSAhL59jr
Lbu04uBdyYYbdqokjzSzuQm0ybw5fURQZs7HC5X2A2SgwP5vs/ekWOnS7G2SxBI4
vnrHef3+cFiEbkj4OAySNbUeY3ftbg333JFkAbyA5bD7DHlEHrUvWRWVzLEWGCJ7
FgfbpqtiyFbLbkimXgVP4GhMA+TaP3XCDa1GgI2sJY9+q0GpX7mz6CBbTz7C/ORk
GgoUFVx5tyVO8E7PHqGOcLTwwpJtsq0geGMn4QaG5qUY9j851zkVOXSVeUo3y7nY
AqRaLqHBBN7xOKs0IQLAJz/5vCEvBEjqAR59NtwA1h9JAUx20VkVO2eu+YaepjU=
=vkVW
-----END PGP SIGNATURE-----
如果想生成單獨的簽名文件锐膜,與文件內容分開存放毕箍,可以使用detach-sign參數(shù)。
gpg --detach-sign test.txt
是一個二進制的數(shù)據道盏,如果想采用ASCII碼形式而柑,要加上armor參數(shù)
gpg --armor --detach-sign test.txt
簽名+加密
上一節(jié)的參數(shù)文捶,都是只簽名不加密。如果想同時簽名和加密媒咳,可以使用下面的命令粹排。
gpg --local-user [發(fā)信者ID] --recipient [接收者ID] --armor --sign --encrypt test.txt
local-user參數(shù)指定用發(fā)信者的私鑰簽名,recipient參數(shù)指定用接收者的公鑰加密涩澡,armor參數(shù)表示采用ASCII碼形式顯示顽耳,sign參數(shù)表示需要簽名,encrypt參數(shù)表示指定源文件妙同。
驗證簽名
我們收到別人簽名后的文件射富,需要用對方的公鑰驗證簽名是否為真。verify參數(shù)用來驗證
gpg --verify test.txt.asc test.txt
說明
如果錯誤之處粥帚,還請給予指出胰耗。謝謝