GPG加密实践与Python调用
GNU Privacy Guard(GnuPG或GPG)是一种加密软件,它是PGP加密软件的满足GPL的替代物。GnuPG依照由IETF订定的OpenPGP技术标准设计。GnuPG用于加密、数字签名及产生非对称钥匙对的软件。
基本用法
安装GnuPG
一般情况下,Linux系统自带GnuPG,输入gpg
可以看到相关的帮助与用法:
gpg (GnuPG) 2.2.12
libgcrypt 1.8.4
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.
......
当然,所有的Linux源中都带有该软件包,使用默认的包管理器即可安装:
(Debian/Ubuntu) sudo apt-get install gpg -y
生成一个密钥对
在终端输入:
gpg --full-generate-key
按步骤操作:
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.(输入秘钥长度,这里我选择2048)
What keysize do you want? (3072) 2048
Requested keysize is 2048 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 (年)
(比如2年2月:2y2m,这里我做演示,所以为2天)
Key is valid for? (0) 2
Key expires at Thu 16 Jul 2020 09:07:42 AM UTC
Is this correct? (y/N) y
GnuPG needs to construct a user ID to identify your key.
Real name: tester(名称)
Email address: [email protected](邮箱)
Comment: test(注释)
You selected this USER-ID:
"tester (test) <[email protected]>"
Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O
......(这里之后会要你输入保护秘钥的密码)
......(最后输出一些信息)
gpg: key 9BFDDC59D3138AA7(这是秘钥ID,可替换下文的tester来作为秘钥标识) marked as ultimately trusted
gpg: revocation certificate stored as '/root/.gnupg/openpgp-
revocs.d/4E9A37A6608115A542D30BF69BFDDC59D3138AA7.rev'
public and secret key created and signed.
pub rsa2048 2020-07-14 [SC] [expires: 2020-07-16]
4E9A37A6608115A542D30BF69BFDDC59D3138AA7
uid tester (test) <[email protected]>
sub rsa2048 2020-07-14 [E] [expires: 2020-07-16]
分享公钥
将你的公钥分享给朋友们,以便验明正身和加密信息:
gpg -a --export tester(秘钥标识,可为邮箱,名称以及秘钥ID) > gpg_pub.key
这个文件格式为:
-----BEGIN PGP PUBLIC KEY BLOCK-----
......
-----END PGP PUBLIC KEY BLOCK-----
私钥导出
这会要你输入密码:
gpg -a --export-secret-keys tester > gpg_pri.key
生成吊销证书
生成一张吊销证书,以备不时之需让秘钥失效,这会要你输入密码:
gpg --gen-revoke test > gpg_revoke.key
按步骤操作:
Create a revocation certificate for this key? (y/N) yes(当然yes)
Please select the reason for the revocation:(选择一个理由)
0 = No reason specified (未指定理由)
1 = Key has been compromised (秘钥被盗用)
2 = Key is superseded (秘钥被取代)
3 = Key is no longer used (不再使用)
Q = Cancel (取消)
(Probably you want to select 1 here)
Your decision? 0
Enter an optional description; end it with an empty line:(一些说明)
> test
Reason for revocation: No reason specified
(No description given)
Is this okay? (y/N) y
如果需要吊销,只需导入该证书即可。
查看&管理
查看已有公钥:
gpg --list-keys
查看已有私钥:
gpg --list-secret-keys
删除一个秘钥:
gpg --delete-key 用户标识
导入一个秘钥:
gpg --import 秘钥文件
输出秘钥指纹:
gpg --fingerprint tester
(比如:4E9A 37A6 6081 15A5 42D3 0BF6 9BFD DC59 D313 8AA7)
加密与解密文件
加密一个文件:
gpg --recipient tester --encrypt demo.txt
(这会在目录下生成一个名为demo.txt.gpg的加密过后的文件)
解密一个文件,这会要求输入密码:
gpg --recipient tester --decrypt demo.txt.gpg > output.text
给文件签名
其实这是我最主要的用法:
gpg --recipient tester --clearsign demo.txt
(这会在目录下生成一个demo.txt.asc文件,包含签名)
单独生成签名:
gpg --recipient tester --armor --detach-sign demo.txt
(这会在目录下生成一个demo.txt.asc文件,只有签名)
验证签名:
gpg --verify demo.txt.asc demo.txt
(若匹配秘钥列表中的一个,则输出如下)
gpg: Signature made Tue 14 Jul 2020 09:45:54 AM UTC
gpg: using RSA key D7AF674BE9E2EA5C9C5EA029FB89B9B6AA70B6DD
gpg: Good signature from "tester <[email protected]>" [ultimate]
与Python
安装相关包
sudo pip3 install python-gnupg
加密&解密
#!/usr/bin/python3
import gnupg
#这指向你的用户目录下的.gnupg文件夹
gpg = gnupg.GPG(gnupghome="/root/.gnupg")
#加密字符串
text = "817"
enc_text = gpg.encrypt(text,"tester")
print("ok: ",enc_text.ok)
print("status: ",enc_text.status)
print("stderr: ",enc_text.stderr)
print(str(enc_text))
#解密字符串
dec_text = gpg.decrypt(str(enc_text),passphrase="password")
print("ok: ",dec_text.ok)
print("status: ",dec_text.status)
print("stderr: ",dec_text.stderr)
print(str(dec_text))
#加密文件&加密文件
with open("demo.txt","rb") as f:
status = gpg.encrypt_file(f,recipients="tester",output="demo.txt.gpg")
print("ok: ",status.ok)
print("status: ",status.status)
print("stderr: ",status.stderr)
with open("demo.txt","rb") as f:
status = gpg.decrypt_file(f,passphrase="password",output="demo.txt")
print("ok: ",status.ok)
print("status: ",status.status)
print("stderr: ",status.stderr)