GPG入门笔记
0. 简介
GPG
是 GNU Privacy Guard
的简写,是GNU
对PGP
技术的实现。PGP
是Pretty Good Privacy
的简写,是一套用于加密的软件。
PGP加密过程如下(来自维基百科 PGP):
PGP
同时利用了对称加密和非对称加密,对文件内容的加密用的是对称加密,对称加密的密钥是每次加密时生成的。由于对称密钥要随密文一起传输,采用了非对称加密算法给对称密钥进行了加密。
1. GPG 的安装
1.1 linux命令行版本
以 CentOS
为例:
$ sudo yum install gpg
或者
$ sudo yum install gnupg
安装成功后,运行 gpg -h
测试下:
$ gpg -h
gpg (GnuPG) 2.0.22
libgcrypt 1.5.3
Copyright (C) 2013 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
Supported algorithms:
Pubkey: RSA, ?, ?, ELG, DSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: MD5, SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
Syntax: gpg [options] [files]
Sign, check, encrypt or decrypt
Default operation depends on the input data
Commands:
-s, --sign make a signature
--clearsign make a clear text signature
-b, --detach-sign make a detached signature
-e, --encrypt encrypt data
-c, --symmetric encryption only with symmetric cipher
-d, --decrypt decrypt data (default)
--verify verify a signature
-k, --list-keys list keys
--list-sigs list keys and signatures
--check-sigs list and check key signatures
--fingerprint list keys and fingerprints
-K, --list-secret-keys list secret keys
--gen-key generate a new key pair
--gen-revoke generate a revocation certificate
--delete-keys remove keys from the public keyring
--delete-secret-keys remove keys from the secret keyring
--sign-key sign a key
--lsign-key sign a key locally
--edit-key sign or edit a key
--passwd change a passphrase
--export export keys
--send-keys export keys to a key server
--recv-keys import keys from a key server
--search-keys search for keys on a key server
--refresh-keys update all keys from a keyserver
--import import/merge keys
--card-status print the card status
--card-edit change data on a card
--change-pin change a card's PIN
--update-trustdb update the trust database
--print-md print message digests
--server run in server mode
Options:
-a, --armor create ascii armored output
-r, --recipient USER-ID encrypt for USER-ID
-u, --local-user USER-ID use USER-ID to sign or decrypt
-z N set compress level to N (0 disables)
--textmode use canonical text mode
-o, --output FILE write output to FILE
-v, --verbose verbose
-n, --dry-run do not make any changes
-i, --interactive prompt before overwriting
--openpgp use strict OpenPGP behavior
(See the man page for a complete listing of all commands and options)
Examples:
-se -r Bob [file] sign and encrypt for user Bob
--clearsign [file] make a clear text signature
--detach-sign [file] make a detached signature
--list-keys [names] show keys
--fingerprint [names] show fingerprints
Please report bugs to <http://bugs.gnupg.org>.
1.2 GUI版本
GUI版本可用gpg4win
:
- gpg4win https://www.gpg4win.org/download.html 我的PGP密钥就是用这个软件生成的。
2. GPG的使用
命令行下gpg
的使用可以参考阮一峰老师的 GPG入门教程 。
2.1 列出密钥
gpg --list-keys
显示结果如下:
/root/.gnupg/pubring.gpg
------------------------
pub 2048R/23E44D6C 2018-03-23
uid liuchunyuan <liucy@xxx.com>
sub 2048R/B94ECCF6 2018-03-23
2.2 导出公钥
形式如下(注意顺序不能反了):
gpg --armor --output pubkey.asc --export [用户ID]
实际执行:
$ gpg --armor --output pubkey.asc --export liuchunyuan
打开文件pubkey.asc
,会是这个样子:
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
mQENBFq0v9sBCAC5aIHudTw2FL68M7cSerPTIECXpPoGv+aIJ+rBMBZLzt+dtqOW
5ZDxD72soiRvK+5Oi5bM1TjS3tZwcu1vjjkSyikzPhyZhm+V8jOxGQ8IBHwF1R+T
... // 内容省略
BADQamN3EBtMzbo/AN3F3PEs5zhG27D5nUkBVX8c
=pKXW
-----END PGP PUBLIC KEY BLOCK-----
2.3 导出私钥
形式如下:
gpg --armor --output prikey.asc --export-secret-keys
执行后,打开 prikey.asc
,内容如下:
-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: GnuPG v2.0.22 (GNU/Linux)
lQOXBFq0v9sBCAC5aIHudTw2FL68M7cSerPTIECXpPoGv+aIJ+rBMBZLzt+dtqOW
5ZDxD72soiRvK+5Oi5bM1TjS3tZwcu1vjjkSyikzPhyZhm+V8jOxGQ8IBHwF1R+T
... // 内容省略
7DBG45UEANBqY3cQG0zNuj8A3cXc8SznOEbbsPmdSQFVfxw=
=4QmL
-----END PGP PRIVATE KEY BLOCK-----
2.4 导入密钥
可以将其他人的公钥或者自己的私钥导入系统。
形式如下:
gpg --import [密钥文件]
2.5 加密文件
形式如下:
gpg --reipient [用户ID] --output demo.txt.gpg --encrypt demo.txt
demo.txt
的内容会先用随机产生的对称加密密钥
进行加密。指定接收文件的用户ID,实际上是用他的公钥加密 对称加密密钥
。
2.6 解密文件
形式如下:
gpg --output demo.txt --decrypt demo.txt.gpg
--decrypt
参数要放在后面,顺序反过来会报错:
$ gpg --decrypt 1.php.asc --output 10.php
usage: gpg [options] --decrypt [filename]
解密文件,是使用自己的私钥把 加密后的对称加密密钥
解开,然后用对称加密密钥解密加密的内容。
2.7 签名
2.7.1 生成二进制格式的验签
gpg --sign demo.txt
2.7.2 生成ASCII格式的验签
gpg --clearsign demo.txt
会生成demo.txt.asc
文件。
实际执行:
$ gpg --clearsign 1.php
1.php
内容如下:
<?php
$res = gnupg_init();
$fp = '236044B09F5A6AFE49FBBB66059715E1B94ECCF6';
gnupg_adddecryptkey($res, "236044B09F5A6AFE49FBBB66059715E1B94ECCF6");
$plain = gnupg_decrypt($res, file_get_contents("1.gpg"));
签名后 1.php.asc`内容如下:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
<?php
$res = gnupg_init();
$fp = '236044B09F5A6AFE49FBBB66059715E1B94ECCF6';
gnupg_adddecryptkey($res, "236044B09F5A6AFE49FBBB66059715E1B94ECCF6");
$plain = gnupg_decrypt($res, file_get_contents("1.gpg"));
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQEcBAEBAgAGBQJbdAD1AAoJEKqyrpYj5E1sfn0H/2MHdzHFVuwfKsEv7Tji1rZ2
2T3Ed4M50evakoZNhaovbcybgxI+wQ5cDft4bVtsnXOKOfave4xPWq0mU2i16W2P
55htKfPr6y9gq4PK1Khb92SRst7FAQMAp8YwjXxpTWtx8Fqqh65jYm9jWiP54fAm
XhnwmkjiA+MHgaybCb5iqQpzdO5YbAve7S3zXQCyo6RGgLhNEvc3cAY1dYSpVl03
3hBA6Lxcl4nTT40qu+CHaGzFoS0zKSsH5d62Lx/zV7oTuVJuGrL+ddO/Wzlu9oBx
WWM0R9kfNGbDNtX+DiPA//FCJl/NkpTaWEiylhTTW9pyAu9Hsa24SBVRua1up5I=
=hxXW
-----END PGP SIGNATURE-----
2.7.3 单独生成签名文件
gpg --detach-sign demo.txt
生成ASCII格式的单独签名文件
gpg --armor --detach-sign demo.txt
实际执行:
$ gpg --armor --detach-sign 1.php
1.php.asc
内容如下:
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
iQEcBAABAgAGBQJbdAGNAAoJEKqyrpYj5E1sWZUH/ieiBRSjdZPD1X1t/Bb+224K
kS3dK9PXoClxpsxp5cZu/hycyZmSo4vpB1mPbQYR2by1KqngUtlrxO+r3YQ7LqrA
E0DRCN845ZTDA00QJkHbGjaCELebtcz+9tdMwWmeu5mzOuuu5VVJZ6WwG6IPC1Va
Ehfy3PDe4SuAvPVjx+gYcdRU998E4DgWTnQ2Y11hm9Ab7F+e7IYipd1CneAgMfRv
Nc6xKd67Ys8/IIu4zNgQyM9apeDBurz+lvOXVCzzAWZaU56XoaUoSBc+UlJdfpAG
zERnz9AFJTnHWjb2TVzxstzDOftYm+ON6iV78DCh5yYDfQ+bWrIkJp3IHOAvx7c=
=KqGr
-----END PGP SIGNATURE-----
2.8 验签
gpg --verify demo.txt.asc demo.txt
实际执行:
$ gpg --verify 1.php.asc 1.php
输出:
gpg: Signature made Wed 15 Aug 2018 06:33:49 PM CST using RSA key ID 23E44D6C
gpg: Good signature from "liuchunyuan <liucy@xxx.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: FB18 B072 1FBE B04B 80C1 635F AAB2 AE96 23E4 4D6C
2.9 加密和签名
gpg --local-user [发信者ID] --recipient [接收者ID] --armor --sign --encrypt demo.txt
实际执行(发信人和收信人都是我自己):
$ gpg --local-user liuchunyuan --recipient liuchunyuan --armor --sign --encrypt 1.php
执行过程中需要确认:
gpg: B94ECCF6: There is no assurance this key belongs to the named user
pub 2048R/B94ECCF6 2018-03-23 liuchunyuan <liucy@xx.com>
Primary key fingerprint: FB18 B072 1FBE B04B 80C1 635F AAB2 AE96 23E4 4D6C
Subkey fingerprint: 2360 44B0 9F5A 6AFE 49FB BB66 0597 15E1 B94E CCF6
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
File `1.php.asc' exists. Overwrite? (y/N) y
加密并签名后的1.php.asc
内容如下:
-----BEGIN PGP MESSAGE-----
Version: GnuPG v2.0.22 (GNU/Linux)
hQEMAwWXFeG5Tsz2AQgAslW9fXCdfuYMsEYbzF3xbIh8HYRnfMcCoGO1u1ctJU6w
8+dOMjsiVcWZwk0YeKcEY8qmcG1V1+lT6mD/yCKryOCf9VNrb/T+rTYzFD7sKlx/
eWYSxBngG7tZU/mfYWLT1iXAjTSDsxXoFuJ1GbzXtWd9korvtbQgGhOf6bv6xCJF
rg1hY/jhr0A5Lfz21HvplysSJit7MZSTgc/fRSvNYNwqTLqRhLOdWXxv0q8+TdYX
8lGYzUCniQu9+KmFbl2LqVqX7SXoukk1wMpm1WSq6uWpRIqvEeiZ7VAduu026TvN
692sDOuQxmFiZ6fwOSFJ4vIpigzBWOY62bvgQrVhndLpAXiIqEnKvenaO7FgztZn
K9SyjApKSX/pDa46QW/LznfUNF8QXLwtG0jZasSZvHqs5KtX666lszjWgcku9HL0
4fkHKlNf25J4Pj4GHZYP+VyXEJA9YMmbmFFGZyBO2IhR9PWpFCDoocjtEPkWjECY
jJw20bF6GszKYdIr4BtJXD7ZHnA35iyxcDduR4C2LZM2WenNqzYiAFsC0M/rKwMF
SKGEDafAQ8x06uu0Jsi2xuyiGraUutAUbR1MdOU585kMo/c7qnJvFgfwMybY+19l
EcwwXHRVaaiQk9FUx0YDQ4nPS7BxOf5umHmctF17o94fToXpFuki40NYiUR4F98W
lcgkUn1JbCXHmMF1/earWtsCK8/7WCbf1AY8BTj7aYJOVa+iQ3uj2gP7I39I9w14
baq7xQc3WrMy6OZ6F/WX2JEXhYz3eY1TXFFRm4/LmMSyWLZPAfBWrCoDJWBMLb96
ODoBZngY/YO2ypbK6NMw9/2qoWUlBgO36GsCjIg1zb8hX/R7dwqPUx1i4eW4sV08
l74F/WezVhct5zdt1MgdYQWaz8aVv/PS1c47k/JJ1+rX6gKaDEu88O7A/QPmZlVV
B8pxQVREavtJHQL8uoseFt48m3txka+/2pex7rCDXtJO2q5g40DujuUfCI9LeEkj
6chQXl6BHuuK3LVsXDfnmI0EQIAiJg==
=FuoF
-----END PGP MESSAGE-----
对该文件解密:
$ gpg --output 10.php --decrypt 1.php.asc
控制台输出:
gpg: encrypted with 2048-bit RSA key, ID B94ECCF6, created 2018-03-23
"liuchunyuan <liucy@ht-xx.com>"
gpg: Signature made Thu 16 Aug 2018 09:17:09 AM CST using RSA key ID 23E44D6C
gpg: Good signature from "liuchunyuan <liucy@ht-xx.com>"
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: FB18 B072 1FBE B04B 80C1 635F AAB2 AE96 23E4 4D6C
对比2.8 验签
一节的内容,看来解密的同时已经做了验签。
查看10.php
,内容如下:
<?php
$res = gnupg_init();
$fp = '236044B09F5A6AFE49FBBB66059715E1B94ECCF6';
gnupg_adddecryptkey($res, "236044B09F5A6AFE49FBBB66059715E1B94ECCF6");
$plain = gnupg_decrypt($res, file_get_contents("1.gpg"));
解密成功。