GitHub REST API v3 for GPG Keys返回的public_key
字段的格式是什么?
例如,命令curl -v -H "Accept: application/vnd.github.cryptographer-preview" https://api.github.com/users/DurandA/gpg_keys
返回以下键:
pub dsa2048/403094DF 2017-09-03 [SC] [expires: 2018-09-03]
uid [ultimate] Arnaud Durand <arnaud.durand@unifr.ch>
sub elg2048/A454F414 2017-09-03 [E] [expires: 2018-09-03]
根据API doc:
public_key
响应字段中返回的数据不是GPG格式的密钥。当用户上载GPG密钥时,将对其进行解析,并提取并存储加密公钥。此加密密钥是此页面上的API返回的密钥。此密钥不适合由GPG等程序直接使用。
是否可以通过CLI或以编程方式使用这些密钥?
答案 0 :(得分:3)
返回的密钥是裸(RSA,DSA,...)密钥,OpenPGP的实现不能将其用于再次将其“包装”在适当的OpenPGP密钥包中。我不建议这样做,为什么你应该能够再次构造 key 数据包,你将没有机会为子项和用户ID构建绑定签名(这需要访问私钥)并且不会成功并构建有用的东西。
在社区中共享密钥的“OpenPGP模型”是从密钥服务器网络(包括所有当前的认证和撤销)获取当前副本,而不是依赖于像GitHub这样的“第三方位置”中可能过时的版本。这可以通过指纹和密钥ID(或多或少唯一地,见下文)寻址特定密钥 - 不搜索邮件地址,每个人都可以创建具有任意用户ID的密钥,密钥服务器不执行任何验证。
相反,再看看API输出,它返回所有键的keyid
个对象(一些用于子键):
[
{
"id": 3,
"primary_key_id": null,
"key_id": "3262EFF25BA0D270",
"public_key": "xsBNBFayYZ...",
"emails": [
{
"email": "mastahyeti@users.noreply.github.com",
"verified": true
}
],
[snip]
}
]
要使用此类密钥ID,请运行gpg --recv-keys <key-id>
。并删除GitHub注意遵循最佳做法并包括完整指纹:
这些64位十六进制值(本例中为3262EFF25BA0D270
)是长密钥ID。虽然对密钥的任何程序化引用都应always include the key's fingerprint, not abbreviated key IDs,但至少它们不提供short key IDs that heavily suffer under collision attacks。
答案 1 :(得分:1)
在撰写本文时,public_key
字段中的内容是在RFC 4880中定义的base64编码的OpenPGP数据包。 gpgpdump对检查它们很有用。例如,
$ curl -s https://api.github.com/users/DurandA/gpg_keys | jq -r '.[0].public_key' | base64 -d | ./gpgpdump
Public-Key Packet (tag 6) (814 bytes)
Version: 4 (current)
Public key creation time: 2017-09-04T06:53:50+08:00
59 ac 87 fe
Public-key Algorithm: DSA (Digital Signature Algorithm) (pub 17)
DSA p (2048 bits)
DSA q (q is a prime divisor of p-1) (256 bits)
DSA g (2046 bits)
DSA y (= g^x mod p where x is secret) (2047 bits)
由于OpenPGP密钥由一系列OpenPGP数据包组成,因此从理论上讲,有可能重建用于验证填充的密钥。为此,需要一个额外的用户ID数据包和一个GnuPG补丁。以下Python 3脚本可用于生成用户ID数据包:
TAG_UID = 13
uid = 'foo@example.com'
# RFC 4880, Sec 4.2.1. Old Format Packet Lengths
header = bytes([0x80 | (TAG_UID << 2), len(uid)])
packet = header + uid.encode('ascii')
sys.stdout.buffer.write(packet)
以下GnuPG补丁即使没有签名也可以强制进行验证。
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 4c172d692..eb4653535 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -177,7 +177,7 @@ check_signature2 (ctrl_t ctrl,
gnupg_compliance_option_string (opt.compliance));
rc = gpg_error (GPG_ERR_PUBKEY_ALGO);
}
- else if (!pk->flags.valid)
+ else if (0)
{
/* You cannot have a good sig from an invalid key. */
rc = gpg_error (GPG_ERR_BAD_PUBKEY);
无论如何,由于没有自签名,因此验证结果不值得信任。