用 GnuPG 簽署、驗證、加密、解密 你的檔案及訊息。
How to get the keypair?#
可以看看上一篇文章「How to use GnuPG to generate PGP key?」。
Signing files#
假設要簽章的文件「hello.txt
」其內容為:
Hello World!
可以使用該指令來簽署檔案:
1# gpg --armor --sign --sign-with <Key-ID> <File-Name>
2gpg --armor --sign --sign-with 36EECBC209A936F5AF9B25A469219C5CB53AF7C3 hello.txt
之後會得出簽章後的檔案「hello.txt.asc
」
後綴「.asc
」表示此檔案為「ASCII
」格式,當然如果你不想要,也可以不使用「--armor, -a
」參數。
--sign
指定要簽章的檔案 (即例子中的檔案hello.txt
)--sign-with
指定要簽章的鑰匙,也就是簽章人 (即例子中的金鑰36EECBC209A936F5AF9B25A469219C5CB53AF7C3
)P.S.
- 「
36EECBC209A936F5AF9B25A469219C5CB53AF7C3
」為我(簽章者)的 Key ID。 - 如果不使用「
--armor, -a
」參數,則預設輸出檔名應該會是「.gpg
」後綴,且內容幾乎會是「Non-printing Character」,因此通常建議使用。 - 你也可以使用上篇文章說到的參數「
--output, -o
」來輸出自訂的檔名。
- 「
至於hello.txt.asc
的內容… 大概長這樣:
-----BEGIN PGP MESSAGE-----
owEB4wEc/pANAwAKAWkhnFy1OvfDAawcYgloZWxsby50eHRg9OQZSGVsbG8gV29y
bGQhCokBswQAAQoAHRYhBDbuy8IJqTb1r5slpGkhnFy1OvfDBQJg9OQZAAoJEGkh
nFy1OvfD2IwL/2L7GahIvctkXMrzsBp+TG3PqhEzriNuyDagmqtmjuWaxo4dqTZO
/iw95YjCMrGthahkDJXi2/wKmA9sy7Z/zUh3GFhKCoATC/Z//nUVKmemtd2ftm9q
2jtO610qOifJyxPhIn3NfXGebeM6Izstgawgg7mdcCh44f3dGn+R9ItIeDfSZ5gb
ZJaAVbBxGAXdjjJatJDP/qIXielvQ5fVjay08c99t64iwrnXxklAKgVgQ7SVzPmW
SNXjaUcBi3HUVcPn/271VzNivnFxQYQKYm9RORkBqDrtdhiOKOD1bTNZD7RWyR3o
AxTeO3kp80y9eUyx6EWMeikyEG8TbNQ2CH6HX+vc1rMLrQkzFSvwbjwT4h1LdYr5
P3uFrhhZ1+BSekeYCW0+xsJ57/1M0lg9Re7JvuH2JIjksG4Vvd3ssCywRGBr1XDH
Y2B6PfANptCwg2FiEvW6kRH0+hrxYsNVH2fVyl9DORR9HllYkIeNszEmhgQDqnlK
oOJR/GGBNGRHSQ==
=j6WE
-----END PGP MESSAGE-----
由「-----BEGIN PGP MESSAGE-----
」至「-----END PGP MESSAGE-----
」中間就是簽章後的訊息。
並且「-----BEGIN PGP MESSAGE-----
」後會空一行 (先不用管,在某些時候會被用來塞資訊)
Verifying files#
要驗證檔案只需要在擁有該檔案相對應公鑰的情況下,輸入指令:
1# gpg --verify <File-Name>
2gpg --verify hello.txt.asc
- 不需要指定解密金鑰嗎?
- 正常情況 GunPG 會自動幫你檢測是否有該檔案所對應的金鑰,因此可以不必手動指定。
若是有著相對應金鑰的情況下,應該可以正常驗證該檔案:
1gpg: Signature made Mon Jul 19 10:31:53 2021 CST
2gpg: using RSA key 36EECBC209A936F5AF9B25A469219C5CB53AF7C3
3gpg: Good signature from "Alpaca0x0 <alpaca0x0@example.com>" [ultimate]
4gpg: WARNING: not a detached signature; file 'hello.txt' was NOT verified!
- 最後一行怎麼有個
WARNING
?- 那只是在提醒 GnuPG 所驗證的檔案為簽章過的「
hello.txt.asc
」而非「hello.txt
」,因此提醒你無法確認hello.txt
是否為原本的檔案。
- 那只是在提醒 GnuPG 所驗證的檔案為簽章過的「
Detach-Signing#
上述的簽章得出的檔案「hello.txt.asc
」是涵蓋原始資訊的,因此你指需要提供該 檔案
及 公鑰
,他人便可以驗證並查看內容。
不過若是你想將簽名
及檔案
分開存放,那麼可以加上「--detach-sign
」參數。
若是簽章檔案時使用參數「--detach-sign
」則表示使用「分離式簽章
」:
1# e.g.
2gpg --armor --detach-sign --sign --sign-with 36EECBC209A936F5AF9B25A469219C5CB53AF7C3 hello.txt
這麼一來,產生出的「hello.txt.asc
」檔案僅僅是簽名
,而不包含原始檔案的內容,因此你必須將公鑰
、原始檔案
、簽名
一並提供,他人才能驗證及查看。
1gpg: assuming signed data in 'hello.txt'
2gpg: Signature made Mon Jul 19 11:04:55 2021 CST
3gpg: using RSA key 36EECBC209A936F5AF9B25A469219C5CB53AF7C3
4gpg: Good signature from "Alpaca0x0 <alpaca0x0@example.com>" [ultimate]
也可以注意到底下不會出現「gpg: WARNING: not a detached signature; file 'hello.txt' was NOT verified!
」的訊息了,因為這時候的「hello.txt
」是受到「hello.txt.asc
」認證過的檔案,可以確保沒有受到竄改。
Decrypting files#
上述的都是簽章及驗證,若是要查看內容則需要用到解密指令:
1# gpg --decrypt <File-Name>
2gpg --decrypt hello.txt.asc
與「--verify
」一樣,不需要指定解密公鑰
若是有對應的公鑰,就可以看到內容及簽章資訊了:
1Hello World!
2gpg: Signature made Mon Jul 19 12:30:52 2021 CST
3gpg: using RSA key 36EECBC209A936F5AF9B25A469219C5CB53AF7C3
4gpg: Good signature from "Alpaca0x0 <alpaca0x0@example.com>" [ultimate]
當然也可以將結果輸出到指定檔案:
1# gpg --output <Output-File-Name> --decrypt <Input-File-Name>
2# gpg --decrypt <Input-File-Name> > <Output-File-Name>
3gpg --output hello.txt.dec --decrypt hello.txt.asc
4# or
5gpg --decrypt hello.txt.asc
Encrypting#
- What is the difference between
--encrypt
and--sign
?--encrypt
- The contents will are NOT able to be seen without have the corresponding key. (Typically used to deliver private content to a specific target)--sign
- Everyone can see the contents, but only with the corresponding key can verify that the file has not been tampered with. (Usually used for some official announcements)
1# gpg --armor --encrypt --recipient <Key-ID> <File-Name>
2gpg --armor --encrypt --recipient 36EECBC209A936F5AF9B25A469219C5CB53AF7C3 hello.txt
p.s. 參數「--recipient, -r
」為指定對象,如例子中指定要執行encrypt
的公鑰,即「36EECBC209A936F5AF9B25A469219C5CB53AF7C3
」。
Sign and Encrypt#
在使用「--sign
」簽名時,可以搭配「--encrypt
」使用。
若我要將檔案「hello.txt
」簽名,並且我希望僅能由我的好友 Bob 接收該檔案,因此我使用 Bob 提供給我的公鑰「CEE24977933B19A42EEA8CB96DC577B036FDDE87
」來將簽名後的檔案加密:
1# gpg --armor --sign --encrypt --sign-with <Your-Private-Key-ID> --recipient <Recipient-Public-Key-ID> --encrypt <File-Name>
2gpg --armor --sign --sign-with 36EECBC209A936F5AF9B25A469219C5CB53AF7C3 --recipient CEE24977933B19A42EEA8CB96DC577B036FDDE87 hello.txt
則檔案「hello.txt.asc
」僅能讓同時擁有 我的公鑰
及 Bob 的私鑰
兩把鑰匙的人解密。
p.s. 用「--recipient, -r
」參數來指定--encrypt
的對象,也就是欲用來加密的公鑰。
References#
《GnuPG documentation》https://gnupg.org/documentation/manpage.html