GnuPG - 指南
13 Apr 2020
PGP是一款基于RSA非对称加密算法的加密软件。而它的GNU发行版即为GnuPG。我们可以利用它生成自定义的公私钥对,并实现对指定内容的加密、解密和签名操作。
GnuPG 安装 §
软件下载 §
访问GnuPG官网进行下载(由于美国限制加密技术出口,该软件只能通过相应的镜像站下载,在此我选用的是日本的镜像站)。
软件安装 §
根据安装向导的提示进行安装。
安装验证 §
打开命令行(cmd,power shell,wsl均可),输入:
$ gpg --version
若产生类似以下的输出即为安装完成:
gpg (GnuPG) 2.2.9
libgcrypt 1.8.3
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://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: /*此处为你的软件主目录*/
Supported algorithms:
Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
CAMELLIA128, CAMELLIA192, CAMELLIA256
Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
Compression: Uncompressed, ZIP, ZLIB, BZIP2
生成密钥 §
使用命令生成自己的密钥:
# 一般场景
$ gpg --gen-key
# 或者,与上者等价
$ gpg --generate-key
# 快速生成密钥
$ gpg --quick-generate-key
# 生成全功能密钥,这里采用这一参数
$ gpg --full-generate-key
输出如下:
$ gpg --full-generate-key
gpg (GnuPG) 2.2.9; Copyright (C) 2018 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算法。
输入1
或者直接回车,系统将询问你所要生成的密钥长度:
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (2048)
输入2048
或者直接回车,系统将询问密钥的有效期:
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
如果密钥仅仅是私人使用,那么完全可以选择第一项,即永不过期。
随后系统将向你确认以上信息的正确性:
Is this correct? (y/N)
输入y
继续。系统将要求你提供个人信息:
GnuPG needs to construct a user ID to identify your key.
Real name:
输入你的真实姓名,下一步:
Email address:
输入你的邮箱地址,下一步:
Comment:
输入注释(可以省略)。
信息录入完毕后,你的ID就生成了:
You selected this USER-ID:
"Zhang San (First key) <ZhangSan@email.com>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit?
根据提示可以修改上述信息(N
:修改姓名,C
:修改注释,E
:修改邮箱),如输入无误,输入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.
系统需要很大的随机字节,而用户随机敲击键盘、移动鼠标等操作将很好地提高系统所需的熵。
之后,密钥就很快的生成出来了!如果看到如下输出,将证明这一点:
...
gpg: key /*一串由用户ID所生成的Hash值*/ marked as ultimately trusted
...
public and secret key created and signed.
pub rsa2048 /*日期*/ [SC]
/*密钥代码*/
uid Zhang San (First key) <ZhangSan@email.com>
sub rsa2048 /*日期*/ [E]
在生成密钥之后,最好再生成生成一个“撤销证书“,用于之后的密钥作废:
# 填入自己的用户ID或者生成的Hash值
$ gpg --gen-revoke <user_id or user_id_hash>
# 或者
$ gpg --generate-revocation <user_id or user_id_hash>
密钥管理 §
列出所有的密钥 §
$ gpg --list-keys
gpg: checking the trustdb
gpg: marginals needed: 3 completes needed: 1 trust model: pgp
gpg: depth: 0 valid: 1 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 1u
/*公钥文件路径*/
------------------------------------------------
pub rsa2048 /*日期*/ [SC] /*公钥特征*/
/*Hash值*/
uid Zhang San (First key) <ZhangSan@email.com>
sub rsa2048 /*日期*/ [E] /*私钥特征*/
...
删除密钥 §
# 删除公钥
$ gpg --delete-keys <user_id or user_id_hash>
# 删除私钥
$ gpg --delete-secret-keys <user_id or user_id_hash>
输出密钥 §
# 生成的密钥以二进制形式存储
# --armor参数可将其转化为ASCII码形式
# 转换公钥
$ gpg --armor --output <output_file> --export <user_id or user_id_hash>
# 转换私钥
$ gpg --armor --output <output_file> --export-secret-keys <user_id or user_id_hash>
上传公钥 §
# 公钥服务器是网络上专门储存用户公钥的服务器
# --send-keys参数可以将公钥上传到服务器
$ gpg --send-keys <user_id or user_id_hash> --keyserver hkp://subkeys.pgp.net
使用上面的命令,你的公钥就被传到了服务器subkeys.pgp.net,然后通过交换机制,所有的公钥服务器最终都会包含你的公钥。
由于公钥服务器没有检查机制,任何人都可以用你的名义上传公钥,所以没有办法保证服务器上的公钥的可靠性。通常,你可以在网站上公布一个公钥指纹,让其他人核对下载到的公钥是否为真。fingerprint参数生成公钥指纹。
$ gpg --fingerprint <user_id or user_id_hash>
加载密钥 §
# --import可以将他人的公钥或者你的其他密钥输入系统
$ gpg --import <key_file>
# 或者在公钥服务器上进行查找
$ gpg --keyserver hkp://subkeys.pgp.net --search-keys <user_id or user_id_hash>
文件的加密和解密 §
加密文件 §
假使你有一个想要加密的文件,该如何操作才能达成你的目标呢?
# --encrypt参数用于加密数据
# --recipient参数用于指定接受者的公钥
$ gpg --recipient <user_id or user_id_hash> --output <output_file> --encrypt <input_file>
解密文件 §
当收信方收到密文后,就可以用自己的私钥进行解密:
# --decrypt参数用于解密数据
$ gpg --decrypt <encrypted_file> --output <output_file>
# 或者直接使用
$ gpg <encrypted_file>
# 解密结果将在命令行直接输出
签名 §
对文件进行签名 §
有时,我们不需要加密文件,只需要对文件签名,表示这个文件确实是发信者本人发出的。
# --sign参数用于签名操作
$ gpg --sign <file>
# 运行结果将会在当前目录生成一个<file>.gpg文件,这个文件就是签名后的文件
# 这个文件默认采用二进制进行存储
# --clear-sign参数用于生成ASCII码的签名文件
$ gpg --clear-sign <file>
# 运行结果将在当前目录生成一个<file>.asc,后缀名asc表示为ASCII格式
# --detach-sign参数单独生成签名文件,与文件内容分开存储
$ gpg --detach-sign <file>
# 运行结果将在当前目录生成一个<file>.sig,该文件是二进制的
# --armor参数将生成ASCII格式的签名文件
$ gpg --armor --detach-sign <file>
签名和加密 §
如果想达成签名和加密同时进行的目的,可以使用:
# --local-user参数指定用发信者的私钥签名,--recipient参数指定用接收者的公钥加密
$ gpg --local-user <send_user_id or send_user_id_hash> --recipient <receive_user_id or receive_user_id_hash> --armor --sign --encrypt <file>
签名验证 §
有了签名后的文件,如何验证该文件签名是否属实呢?
# --verify用于签名验证
$ gpg --verify <file>.asc <file>