我想对我编写的一些 Python 代码文件进行签名,因为它们是我某个项目的插件模块。为了分发它,我希望用户可以确保插件经过验证且安全(因为是由我或我信任的人编写的)并且未被修改。
该软件只是一个开源业余项目,因此我不想花钱购买官方证书。相反,我认为主程序始终有效,无需额外验证即可信任。如果有人从我的 GitHub 存储库以外的任何位置下载它,那是他们的错。
据我所知,签名通常是通过创建非对称密钥对、从代码文件计算强加密哈希值(例如 SHA-512)、使用我的私钥加密哈希并将该签名存储在单独的文件中来完成的,该文件将与原始代码文件一起发送。
然后,主程序必须使用以纯文本形式保存在主程序源代码中的公钥解密签名,计算代码文件的相同哈希函数,然后将其与解密的哈希函数进行比较。如果它们匹配,则可以信任该插件。
现在我的问题是:
如何使用 Ubuntu 工具轻松创建强非对称密钥对以及如何轻松计算文件的加密哈希值?
在脚本中自动执行签名过程(始终使用相同的密钥)会很棒。
答案1
这个答案的大部分内容摘自Arch 维基和GnuPG 文档。此答案中的任何建议均纯属我个人意见,请勿当真。
创建 PGP 密钥
图形用户界面
打开密码和密钥应用程序(又名
seahorse
),然后点击+
(或转到文件->新的或按CtrlN) 查看:选择PGP 密钥,然后输入您的详细信息。我正在模仿 Byte Commander:
RSA 和 2048 位对于大多数用途来说都很好。如果您只想使用它进行签名,请选择RSA(仅签名)下拉菜单中的选项,但你不需要 - 这可以使用子密钥。您可以发表评论。保留密钥的有效期也很有用。单击Create。
输入一个足够长的密码(我的意思是长的(在我看来,我的例子很短),然后单击Ok:
与 CLI 不同,Seahorse 似乎没有任何反馈。等待一段时间,做你想做的任何事情,同时它会收集熵并创建一个密钥。这可能需要一段时间。之后,你会看到他们输入PGP 密钥部分:
命令行界面
要从命令行生成密钥,只需运行gpg --gen-key
。它将要求您提供与 GUI 相同的详细信息:
$ gpg --gen-key
gpg (GnuPG) 1.4.16; Copyright (C) 2013 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?
RSA keys may be between 1024 and 4096 bits long.
What keysize do you want? (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
Key is valid for? (0) 1y
Key expires at Tuesday 27 September 2016 03:45:19 PM IST
Is this correct? (y/N) y
You need a user ID to identify your key; the software constructs the user ID
from the Real Name, Comment and E-mail Address in this form:
"Heinrich Heine (Der Dichter) <[email protected]>"
Real name: Byte Commander
E-mail address: [email protected]
Comment:
You selected this USER-ID:
"Byte Commander <[email protected]>"
Change (N)ame, (C)omment, (E)-mail or (O)kay/(Q)uit? o
You need a Passphrase to protect your secret key.
passphrase not correctly repeated; try again.
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, use the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 186 more bytes)
.....+++++
+++++
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, use the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 80 more bytes)
....+++++
Not enough random bytes available. Please do some other work to give
the OS a chance to collect more entropy! (Need 83 more bytes)
...+++++
gpg: key 8AE670A6 marked as ultimately trusted
public and secret key created and signed.
gpg: checking the trustdb
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u
gpg: next trustdb check due at 2016-09-26
pub 2048R/8AE670A6 2015-09-28 [expires: 2016-09-27]
Key fingerprint = 82D9 0644 B265 8E75 1E01 538B B479 3CF4 8AE6 70A6
uid Byte Commander <[email protected]>
sub 2048R/0E2F4FD8 2015-09-28 [expires: 2016-09-27]
注意 GnuPG 告诉我们它需要更多的熵。希望海马也需要。但话又说回来,感觉 GnuPG 就像奥利弗·特威斯特一样。:P
发布你的密钥
现在,我们需要获取我们的公钥,以便人们可以使用它来验证事物。
图形用户界面
返回seahorse
应用程序中的 PGP 密钥列表(见最后一张屏幕截图)。选择要导出的密钥,然后在偏僻的菜单,选择同步和发布密钥:
如果您尚未选择要发布的服务器,该Sync按钮将被禁用。单击以下按钮即可选择发布服务器Key Servers:
我选择了 Ubuntu 的服务器。
现在,您可以单击Sync按钮并将其发布到Ubuntu 的密钥服务器(抱歉,Ubuntu,发了垃圾邮件!)
命令行界面
使用 CLI,您需要要发布的密钥的密钥 ID。它是创建密钥时输出的最后一行 ( 8AE670A6
)。如果您不记得它是什么,只需运行gpg --list-keys
。要发布:
$ gpg --keyserver pgp.mit.edu --send-keys 8AE670A6
gpg: sending key 8AE670A6 to hkp server pgp.mit.edu
签名
我还不知道有哪种 GUI 方法可以方便地签署文件。
创建要签名的文件后,转到终端。尝试gpg --list-keys
:
$ gpg --list-keys
/home/muru/.gnupg/pubring.gpg
---------------------------
pub 2048R/F7878B0C 2015-09-28 [expires: 2016-09-26]
uid Byte Commander <[email protected]>
sub 2048R/345B9A4F 2015-09-28 [expires: 2016-09-26]
您可以使用两种方法对文件进行签名:
加密签名
$ gpg --sign --output examples.sig examples.desktop
You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28
gpg: Invalid passphrase; please try again ...
You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28
如果您处于桌面会话中,则可能会看到图形密码提示。例如,在 GNOME 中:
如果收件人有您的公钥,他们可以验证它,或获取解密的内容:
$ gpg --verify examples.sig
gpg: Signature made Monday 28 September 2015 03:25:00 PM IST using RSA key ID F7878B0C
gpg: Good signature from "Byte Commander <[email protected]>"
$ gpg --decrypt examples.sig
[Desktop Entry]
Version=1.0
Type=Link
Name=Examples
Name[aa]=Ceelallo
...
URL=file:///usr/share/example-content/
Icon=folder
X-Ubuntu-Gettext-Domain=example-content
gpg: Signature made Monday 28 September 2015 03:25:00 PM IST using RSA key ID F7878B0C
gpg: Good signature from "Byte Commander <[email protected]>"
明文签名
例如,在发送邮件时,您可能不想加密内容。在这种情况下,请使用以下--clearsign
选项:
$ gpg --clearsign examples.desktop
You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28
$ cat examples.desktop.asc
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
[Desktop Entry]
Version=1.0
Type=Link
Name=Examples
Name[aa]=Ceelallo
...
URL=file:///usr/share/example-content/
Icon=folder
X-Ubuntu-Gettext-Domain=example-content
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
iQEcBAEBAgAGBQJWCRAaAAoJEGUZkqX3h4sMBWsH/1yw+G0v5Ck+T3PBS90SkvC8
5C0FJeGVr0AgYQohhsE3zEGQ7nn53N7JsvNlF6VccvN99DZIp18JbrJ+qs5hWjtg
KU/ACleR5dvVrJgfjppkuC8Q3cAudvqciKlLjA7Xycr3P49oCNCy8k/ue2TrgCvS
mMb5IS/kqpO7wrOMBAR0c/2CjQsA91S1/YK7DbuUqeNgEzW1grsI7XZPhiDGpAib
D20HWrbdLhklAEJuo1EvuOIggW6MF6ksxDoVapsUzQalD0TWEq6OnvzIS5qhITrc
XaDPQJpiHyCyINnL5aZCUwr2uon7osJ+2a8Ahp1REpzIZTdND9jA5NWSel5+yAs=
=ZrtB
-----END PGP SIGNATURE-----
签名,使用单独的文件进行签名(分离签名)
最后,对于某些文件,您不能在文档中包含签名。例如,打包文件或存储库的元数据都具有特定性质的内容,不容易允许嵌入签名。在这种情况下,您可以使用以下选项--detached-sig
:
$ gpg --output examples.desktop.sig --detach-sign examples.desktop
You need a passphrase to unlock the secret key for
user: "Byte Commander <[email protected]>"
2048-bit RSA key, ID F7878B0C, created 2015-09-28
$ gpg --verify examples.desktop.sig examples.desktop
gpg: Signature made Monday 28 September 2015 03:35:55 PM IST using RSA key ID F7878B0C
gpg: Good signature from "Byte Commander <[email protected]>"
笔记
在加密+签名和分离签名中,输出是二进制的。您可以使用选项 (ASCII-armoured)gpg
让 GnuPG 输出 base64 编码的数据。--armor
自动化
要进行脚本签名,您可以:
- 对密钥使用空密码
- 根据您的 GnuPG 版本,通过 发送密码
stdin
。请参阅这篇 Unix 和 Linux 文章一些选项。
答案2
使用 gpg 创建非对称密钥
gpg --gen-key
使用 gpg 签署你的文件(使用你的私钥)
gpg --output foo.sig --detach-sig foo.py
测试签名文件(使用你的公钥)
gpg --verify foo.sig foo.py
示例输出
% gpg --verify foo.sig foo.py gpg: Signature made Mo 28 Sep 2015 12:46:04 CEST using RSA key ID 89B30DEC gpg: Good signature from "Your Name <[email protected]>" % echo "bad" >> foo.py % gpg --verify foo.sig foo.py gpg: Signature made Mo 28 Sep 2015 12:46:04 CEST using RSA key ID 89B30DEC gpg: BAD signature from "Your Name <[email protected]>"