加密工具 - GPG入门
目录
1 GPG是什么
GPG即GnuPG(the GNU Privacy Guard, GNU加密保护),是一款开源加密软件,遵循 RFC4880(OpenPGP标准)。如下是主页介绍:
GnuPG is a complete and free implementation of the OpenPGP standard as defined by RFC4880 (also known as PGP). GnuPG allows you to encrypt and sign your data and communications; it features a versatile(通用的) key management system, along with access modules for all kinds of public key directories. GnuPG, also known as GPG, is a command line tool with features for easy integration with other applications. A wealth of frontend applications and libraries are available. GnuPG also provides support for S/MIME and Secure Shell (ssh).
Since its introduction in 1997, GnuPG is Free Software (meaning that it respects your freedom). It can be freely used, modified and distributed under the terms of the GNU General Public License.
The current version of GnuPG is 2.2.8. See the download page for other maintained versions.
Gpg4win is a Windows version of GnuPG featuring a context menu tool, a crypto manager, and an Outlook plugin to send and receive standard PGP/MIME mails. The current version of Gpg4win is 3.1.1.
2 安装
2.1 Debian
~$ sudo apt-get install gnupg
2.2 msys
~$ pacman -S gnupg # or you can search candidates includes key gnupg by command: ~$ pacman -Ss gnupg
2.3 源码安装
使用Git获取源码:
~$ git clone git://git.gnupg.org/gnupg.git
或者下载源码包:https://gnupg.org/download/index.html
编译安装:
~$ ./autogen.sh *** Activating trailing whitespace git pre-commit hook. *** For more information see this thread: https://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084.html To deactivate this pre-commit hook again move .git/hooks/pre-commit and .git/hooks/pre-commit.sample out of the way. ‘.git/hooks/pre-commit.sample’ -> ‘.git/hooks/pre-commit’ autogen.sh: *** Adding GIT filter.cleanpo.clean configuration. *** Activating commit log message check hook. *** ‘build-aux/git-hooks/commit-msg’ -> ‘.git/hooks/commit-msg’ autogen.sh: Running aclocal -I m4 ... autogen.sh: Running autoheader... autogen.sh: Running automake --gnu ... autogen.sh: Running autoconf ... autogen.sh: You may now run: ./configure --sysconfdir=/etc --enable-maintainer-mode && make ~$ ./configure --sysconfdir=/etc --enable-maintainer-mode && make ~$ sudo make install
如果系统太老,库版本兼容性不满足报错,建议直接安装二进制,或下载较老版本gnupg,或者尝试升级操作系统。例如:
~$ ./configure --sysconfdir=/etc --enable-maintainer-mode && make ... configure: *** *** You need libassuan to build this program. *** This library is for example available at *** https://gnupg.org/ftp/gcrypt/libassuan/ *** (at least version 2.5.0 (API 2) is required). configure: error: *** *** Required libraries not found. Please consult the above messages *** and install them before running configure again. ***
3 使用介绍
3.1 生成密钥
~$ gpg --gen-key
Linux下版本\texttt{--gen-key}部分参数是默认的,使用如下命令对所有选项进行设置:
~$ gpg --full-generate-key
示例:
~$ gpg --full-generate-key gpg (GnuPG) 2.1.18; Copyright (C) 2017 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. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) 4096 Requested keysize is 4096 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 0 Key does not expire at all Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: test Name must be at least 5 characters long Real name: gpgtest Email address: [email protected] Comment: GPG test for blog You selected this USER-ID: "gpgtest (GPG test for blog) <[email protected]>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: key 82159169CFBF69E6 marked as ultimately trusted gpg: revocation certificate stored as '/home/yanyg/.gnupg/openpgp-revocs.d/4F2F97E03BFBF466032ADFB382159169CFBF69E6.rev' public and secret key created and signed. pub rsa4096 2018-06-11 [SC] 4F2F97E03BFBF466032ADFB382159169CFBF69E6 4F2F97E03BFBF466032ADFB382159169CFBF69E6 uid gpgtest (GPG test for blog) <[email protected]> sub rsa4096 2018-06-11 [E]
其中需要选择/输入的内容包括:密钥种类、密钥长度、有效期、真实姓名、邮件地址等。
3.2 密钥管理
3.2.1 密钥列表
其中 gpgtest 是新生成的。
~$ gpg --list-keys gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: pgp gpg: depth: 0 valid: 2 signed: 1 trust: 0-, 0q, 0n, 0m, 0f, 2u gpg: depth: 1 valid: 1 signed: 0 trust: 1-, 0q, 0n, 0m, 0f, 0u gpg: next trustdb check due at 2020-06-09 /home/yanyg/.gnupg/pubring.kbx ------------------------------ pub rsa2048 2018-06-10 [SC] [expires: 2020-06-09] D01A8EDEF8F2F0A3B5C627F7531EDD4DBF9F0F5B uid [ultimate] yanyg <[email protected]> sub rsa2048 2018-06-10 [E] [expires: 2020-06-09] pub rsa2048 2018-06-10 [SC] [expires: 2020-06-09] 321A80E17CFEB82B9913E30F43886FD7AC849DDB uid [ full ] root1 <[email protected]> sub rsa2048 2018-06-10 [E] [expires: 2020-06-09] pub rsa4096 2018-06-11 [SC] 4F2F97E03BFBF466032ADFB382159169CFBF69E6 uid [ultimate] gpgtest (GPG test for blog) <[email protected]> sub rsa4096 2018-06-11 [E] ~$ gpg --list-keys --keyid-format short pub rsa4096/CFBF69E6 2018-06-11 [SC] 4F2F97E03BFBF466032ADFB382159169CFBF69E6 uid [ultimate] gpgtest (GPG test for blog) <[email protected]> sub rsa4096/2EF4FC4B 2018-06-11 [E]
3.2.2 删除密钥
~$ gpg --delete-key [UID]
/UID/可以是用户名(比如gpgtest)、邮箱(比如[email protected])、或者Hash 值(比如CFBF69E6)。
3.2.3 导出公钥
# binary pub key ~$ gpg --output gpgtest.pub --export gpgtest # ascii pub key ~$ gpg --armor --output gpgtest.pub --export gpgtest
3.2.4 上传公钥
~$ gpg --keyserver certserver.pgp.com --send-key 82159169CFBF69E6
其中/key/不能使用UID,需要使用指纹,至少需要long格式指纹,来自下面命令:
gpg --list-key --keyid-format long gpgtest pub rsa4096/82159169CFBF69E6 2018-06-11 [SC] 4F2F97E03BFBF466032ADFB382159169CFBF69E6 uid [ultimate] gpgtest (GPG test for blog) <[email protected]> sub rsa4096/9D5CD5E32EF4FC4B 2018-06-11 [E]
/man/页描述为"Fingerprints may be used instead of key IDs."
3.2.5 导入公钥
导入:
~# gpg --import gpgtest.pub gpg: key 82159169CFBF69E6: public key "gpgtest (GPG test for blog) <gpgtest@gmail.com>" imported gpg: Total number processed: 1 gpg: imported: 1
设置可信:
~# gpg --edit-key gpgtest gpg> help quit quit this menu save save and quit help show this help fpr show key fingerprint grip show the keygrip list list key and user IDs uid select user ID N key select subkey N check check signatures sign sign selected user IDs [* see below for related commands] lsign sign selected user IDs locally tsign sign selected user IDs with a trust signature nrsign sign selected user IDs with a non-revocable signature deluid delete selected user IDs delkey delete selected subkeys delsig delete signatures from the selected user IDs pref list preferences (expert) showpref list preferences (verbose) trust change the ownertrust revsig revoke signatures on the selected user IDs enable enable key disable disable key showphoto show selected photo IDs clean compact unusable user IDs and remove unusable signatures from key minimize compact unusable user IDs and remove all signatures from key * The 'sign' command may be prefixed with an 'l' for local signatures (lsign), a 't' for trust signatures (tsign), an 'nr' for non-revocable signatures (nrsign), or any combination thereof (ltsign, tnrsign, etc.). gpg> trust pub rsa4096/82159169CFBF69E6 created: 2018-06-11 expires: never usage: SC trust: unknown validity: unknown sub rsa4096/9D5CD5E32EF4FC4B created: 2018-06-11 expires: never usage: E [ unknown] (1). gpgtest (GPG test for blog) <[email protected]> Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 4 pub rsa4096/82159169CFBF69E6 created: 2018-06-11 expires: never usage: SC trust: full validity: unknown sub rsa4096/9D5CD5E32EF4FC4B created: 2018-06-11 expires: never usage: E [ unknown] (1). gpgtest (GPG test for blog) <[email protected]> Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> save Key not changed so no update needed.
3.2.6 导入私钥
~$ gpg --export-secret-keys gpgtest > gpgtest.priv # Change to another account ~# gpg --allow-secret-key-import --import gpgtest.priv # change trust to 5 gpg --edit-key gpgtest gpg (GnuPG) 2.1.18; Copyright (C) 2017 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. Secret key is available. sec rsa4096/82159169CFBF69E6 created: 2018-06-11 expires: never usage: SC trust: full validity: unknown ssb rsa4096/9D5CD5E32EF4FC4B created: 2018-06-11 expires: never usage: E [ unknown] (1). gpgtest (GPG test for blog) <[email protected]> gpg> trust sec rsa4096/82159169CFBF69E6 created: 2018-06-11 expires: never usage: SC trust: full validity: unknown ssb rsa4096/9D5CD5E32EF4FC4B created: 2018-06-11 expires: never usage: E [ unknown] (1). gpgtest (GPG test for blog) <[email protected]> Please decide how far you trust this user to correctly verify other users' keys (by looking at passports, checking fingerprints from different sources, etc.) 1 = I don't know or won't say 2 = I do NOT trust 3 = I trust marginally 4 = I trust fully 5 = I trust ultimately m = back to the main menu Your decision? 5 Do you really want to set this key to ultimate trust? (y/N) y sec rsa4096/82159169CFBF69E6 created: 2018-06-11 expires: never usage: SC trust: ultimate validity: unknown ssb rsa4096/9D5CD5E32EF4FC4B created: 2018-06-11 expires: never usage: E [ unknown] (1). gpgtest (GPG test for blog) <[email protected]> Please note that the shown key validity is not necessarily correct unless you restart the program. gpg> save Key not changed so no update needed. ~# gpg --list-keys gpg: checking the trustdb gpg: marginals needed: 3 completes needed: 1 trust model: pgp gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u gpg: next trustdb check due at 2020-06-09 /root/.gnupg/pubring.kbx ------------------------ pub rsa2048 2018-06-10 [SC] [expires: 2020-06-09] 321A80E17CFEB82B9913E30F43886FD7AC849DDB uid [ultimate] root1 <[email protected]> sub rsa2048 2018-06-10 [E] [expires: 2020-06-09] pub rsa4096 2018-06-11 [SC] 4F2F97E03BFBF466032ADFB382159169CFBF69E6 uid [ultimate] gpgtest (GPG test for blog) <[email protected]> sub rsa4096 2018-06-11 [E]
修改后信任模式从unknown改为ultimate。
3.3 签名与签名验证
对文件进行签名:
# generate test files ~$ dd if=/dev/urandom of=test.data bs=1K count=4 ~$ ls -lh test.data -rw-r--r-- 1 yanyg yanyg 4.0K Jun 11 14:32 test.data ~$ gpg --local-user gpgtest --sign test.data ~$ ls -lh test.data* -rw-r--r-- 1 yanyg yanyg 4.0K Jun 11 14:32 test.data -rw-r--r-- 1 yanyg yanyg 4.7K Jun 11 14:34 test.data.gpg gpg --verify test.data.gpg gpg: Signature made Mon 11 Jun 2018 02:34:03 PM CST gpg: using RSA key 4F2F97E03BFBF466032ADFB382159169CFBF69E6 gpg: issuer "[email protected]" gpg: Good signature from "gpgtest (GPG test for blog) <[email protected]>" [ultimate] ~$ echo $? 0
针对特定 key 进行签名验证:
~$ gpg --output gpgtest.gpg --export gpgtest ~$ gpg --no-default-keyring --keyring $PWD/gpgtest.gpg --verify test.data.gpg gpg: Signature made Mon 11 Jun 2018 02:34:03 PM CST gpg: using RSA key 4F2F97E03BFBF466032ADFB382159169CFBF69E6 gpg: issuer "[email protected]" gpg: Good signature from "gpgtest (GPG test for blog) <[email protected]>" [ultimate] ~$ echo $? 0 ~$ gpg --no-default-keyring --keyring $PWD/yanyg.gpg --verify test.data.gpg gpg: Signature made Mon 11 Jun 2018 02:34:03 PM CST gpg: using RSA key 4F2F97E03BFBF466032ADFB382159169CFBF69E6 gpg: issuer "[email protected]" gpg: Can't check signature: No public key ~$ echo $? 2
–keyring 参数需要使用绝对路径,否则报告找不到密钥。
–sign 签名采用二进制存储,如果想保存为纯文本,使用参数 –cleansign :
~$ echo "plain text" >> test.txt ~$ gpg --clearsign test.txt ~$ ls -lh test.txt* -rw-r--r-- 1 yanyg yanyg 11 Jun 11 14:45 test.txt -rw-r--r-- 1 yanyg yanyg 548 Jun 11 14:45 test.txt.asc ~$ cat test.txt.asc cat test.txt.asc -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 plain text -----BEGIN PGP SIGNATURE----- iQEzBAEBCAAdFiEE0BqO3vjy8KO1xif3Ux7dTb+fD1sFAlseGooACgkQUx7dTb+f D1v/DQgAnn75lyOmcX4TJFMj2FV8J2JVjY8Hbp71jMO68x9j1Kao8pemvMMXC87w zi80ZfQbiMImpRZG90ObF/8NHkDT/uqcg4yqHnTbfpmMvlTvUcX6AbOBqINC4WG9 89P8JelyfiA/3x5asow3iL2HBITtCEVoYKtwrMJSgfFHd9q/CJjdAx67O0hakzEZ i1E94rBslfguzO8mRlqvj7b8vEWdGJpXtCPTLhgNKg1Grx9vOhAfhLHl3Vgb+PKB bVl1EZ2CTBuVk4ruNWBlS0FUo5+gAolicYoNT4v4uDy7AXjKY6dIs9qsbmKBbNN0 lXAROEL0pBiIOtYkx531LfwfX69bkg== =VsDH -----END PGP SIGNATURE-----
一般建议签名与文件分离:
~$ gpg --local-user gpgtest --detach-sign test.data ~$ ls -lh test.data* -rw-r--r-- 1 yanyg yanyg 4.0K Jun 11 14:32 test.data -rw-r--r-- 1 yanyg yanyg 4.7K Jun 11 14:34 test.data.gpg -rw-r--r-- 1 yanyg yanyg 585 Jun 11 14:47 test.data.sig ~$ gpg --verify test.data.sig test.data gpg: Signature made Mon 11 Jun 2018 02:47:22 PM CST gpg: using RSA key 4F2F97E03BFBF466032ADFB382159169CFBF69E6 gpg: issuer "[email protected]" gpg: Good signature from "gpgtest (GPG test for blog) <[email protected]>" [ultimate] # Give wrong file: ~$ gpg --verify test.data.sig test.txt gpg: Signature made Mon 11 Jun 2018 02:47:22 PM CST gpg: using RSA key 4F2F97E03BFBF466032ADFB382159169CFBF69E6 gpg: issuer "[email protected]" gpg: BAD signature from "gpgtest (GPG test for blog) <[email protected]>" [ultimate]
ASCII格式签名分离:
~$ gpg --armor --detach-sign test.txt File 'test.txt.asc' exists. Overwrite? (y/N) y yanyg@pc:~/org$ cat test.txt.asc -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEE0BqO3vjy8KO1xif3Ux7dTb+fD1sFAlseG20ACgkQUx7dTb+f D1sCpgf/d7gh5oaQ50K6CeL6VnFNL54olDcVIaGd6Trjz0smCYuszmVZ2s2j7C0d ScZkNVQW9yGHj7QURF8HiFfHU44bLvSSkE7H7sS4lhPI1x1EFRNziyeyL4tCQVNj /muhyDMgAEJ+I8YBsTew5bAT3c7+EyvKACOP0HUqN0ePJFHBeN4hjzeQ+L2Tr6k4 rUETZPmRmYbEKS0Sn85J2ztQbKbHQr5VQ11UmdIsGHIM4tZuf57BBXoD0QCzPzJg OQBs4tQZfPsC1rfVZgg8GgxhVcfCRRNOO/vtz+aiVgzIf+IIRAQnnVvj2lkpVi2E IuSb+9CDA/f4W2VFUka8xFg/h2EBvw== =YAAi -----END PGP SIGNATURE----- ~$ gpg --verify test.txt.asc test.txt gpg: Signature made Mon 11 Jun 2018 02:49:17 PM CST gpg: using RSA key D01A8EDEF8F2F0A3B5C627F7531EDD4DBF9F0F5B gpg: Good signature from "yanyg <[email protected]>" [ultimate] ~$ gpg --verify test.txt.asc test.data gpg: Signature made Mon 11 Jun 2018 02:49:17 PM CST gpg: using RSA key D01A8EDEF8F2F0A3B5C627F7531EDD4DBF9F0F5B gpg: BAD signature from "yanyg <[email protected]>" [ultimate]
3.4 加密解密
使用 –encrypt 参数加密, –decrypt 参数解密:
~$ gpg --recipient gpgtest --output test.txt.enc --encrypt test.txt ~$ ls -lh test.txt test.txt.enc -rw-r--r-- 1 yanyg yanyg 11 Jun 11 14:45 test.txt -rw-r--r-- 1 yanyg yanyg 607 Jun 11 14:53 test.txt.enc ~$ gpg --decrypt test.txt.enc gpg: encrypted with 4096-bit RSA key, ID 9D5CD5E32EF4FC4B, created 2018-06-11 "gpgtest (GPG test for blog) <[email protected]>" plain text ~$ gpg --quiet --decrypt test.txt.enc plain text
在当前版本中, –secret-keyring 已经标记为废弃的,私钥必须导入之后才可使用:
man: –secret-keyring file This is an obsolete option and ignored. All secret keys are stored in the ‘private-keys-v1.d’ directory below the GnuPG home directory.
~$ gpg --export-secret-keys gpgtest > gpgtest.priv # change to root ~# gpg --allow-secret-key-import --import gpgtest.priv gpg: key 82159169CFBF69E6: public key "gpgtest (GPG test for blog) <gpgtest@gmail.com>" imported gpg: key 82159169CFBF69E6: secret key imported gpg: Total number processed: 1 gpg: imported: 1 gpg: secret keys read: 1 gpg: secret keys imported: 1 ~# gpg --quiet --decrypt test.txt.enc plain text
3.5 加密同时签名
使用本地私钥签名,使用接收者公钥加密:
~$ gpg --local-user gpgtest --recipient root1 --output my.enc --sign --encrypt my.txt # Change to root to verify & decrypt ~# gpg --quiet --decrypt my.enc
接收者需要有发送者的公钥进行签名验证,私钥进行解密。可能会发生告警,此时需要设置 key 为可信的。
加密同时采用分离签名(–detach-sign),无法进行解密验证。或者我未找到正确组合参数。
4 其他
4.1 私钥备份保护
- 没有完美的方法
- 设置健壮的密码
- 保存到本地GIT或拷贝到安全、私有介质上
5 References
- 阮一峰GPG入门教程
- http://www.ruanyifeng.com/blog/2013/07/gpg.html
- GnuPG home
- https://gnupg.org/
- GnuPG Manuals
- https://www.gnupg.org/documentation/manuals.html