使用 ssh-keygen 创建适合 DKIM 设置的一对密钥

使用 ssh-keygen 创建适合 DKIM 设置的一对密钥

问题

创建一对适合DKIM使用的设置的密钥的正确方法是什么ssh-keygen

给出相应的解决方案openssl

# creates a private key
openssl genrsa -out sample.key 1024

# creates a public key 
openssl rsa -in sample.key -pubout -out sample.pub

故事

我尝试DKIM使用以下步骤生成密钥:

# creates a pair of keys: sample & sample.pub
ssh-keygen -m PEM -t rsa -b 1024 -f sample

# coverts the public key into the PEM format
ssh-keygen -f sample.pub -m PEM -e > sample.pem.pub

PEM公钥内容示例:

-----BEGIN RSA PUBLIC KEY-----
MIGJAoGBAOO3Emm+KdOKKhwlCjLXIE1R76KlWY6xSVfHsjE3uuMcF0BDKhJS2Kg3
WjhdnV2z5XAQDAxknQvx+sxxbsBye6Zc2VnNA9upDVVlNc4I6zl1N75CY7F1Nfbj
wDrpWqGJuBPsousqj79dJ/JM0pzCn71IkEumU2Ck3AULSnT9MLeZAgMBAAE=
-----END RSA PUBLIC KEY-----

建造DKIM記錄:

v=DKIM1; p=MIGJAoGBAOO3Emm+KdOKKhwlCjLXIE1R76KlWY6xSVfHsjE3uuMcF0BDKhJS2Kg3WjhdnV2z5XAQDAxknQvx+sxxbsBye6Zc2VnNA9upDVVlNc4I6zl1N75CY7F1NfbjwDrpWqGJuBPsousqj79dJ/JM0pzCn71IkEumU2Ck3AULSnT9MLeZAgMBAAE=

我用了https://dkimcore.org/c/keycheck验证 DNS 记录,但提供的值失败,并显示以下消息:

这似乎不是一个有效的 RSA 公钥:RSA.xs:178:OpenSSL 错误:blib/lib/Crypt/OpenSSL/RSA.pm(自动拆分为 blib/lib/auto/Crypt/OpenSSL/RSA/new_public_key.al)第 91 行处的标签错误。

尝试过这些版本:

$ ssh -V
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
OpenSSH_8.1p1, OpenSSL 1.1.1d  10 Sep 2019
OpenSSH_9.4p1, OpenSSL 3.1.2 1 Aug 2023

幸运的是,我找到了上面提到的解决方法openssl。但是由于ssh-keygen 频繁地 提及作为生成密钥的有效工具DKIM,我想知道,方法到底是什么?

答案1

总结

生成一对密钥:

ssh-keygen -t rsa -b 1024 -f sample

将公钥转换为以下PKCS #8格式:

ssh-keygen -f sample.pub -m PKCS8 -e > sample.pub.pem

笔记

互联网标准 RFC6376指定DKIM 记录的默认密钥类型为 RSA,对应的公钥数据为 base64 编码的 ASN.1 DER 编码的 RSAPublicKey。

对初始公钥的检查显示:

    0:d=0  hl=3 l= 137 cons: SEQUENCE
    3:d=1  hl=3 l= 129 prim:  INTEGER           :B758174EDA...bytes...179D51DD18F9
  135:d=1  hl=2 l=   3 prim:  INTEGER           :010001

解决方案结果的检查:

openssl asn1parse -i -inform PEM -in sample.pub.pem

显示:

    0:d=0  hl=3 l= 159 cons: SEQUENCE
    3:d=1  hl=2 l=  13 cons:  SEQUENCE
    5:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
   16:d=2  hl=2 l=   0 prim:   NULL
   18:d=1  hl=3 l= 141 prim:  BIT STRING

这实际上是密钥所需的包装器。BIT STRING也可以检查 18 处:

openssl asn1parse -i -inform PEM -in sample.pub.pem -strparse 18
    0:d=0  hl=3 l= 137 cons: SEQUENCE
    3:d=1  hl=3 l= 129 prim:  INTEGER           :B758174EDA...same bytes...1DD18F9
  135:d=1  hl=2 l=   3 prim: INTEGER           :010001

man on 的最新版本ssh-keygen 笔记使用-m PEM将导致密钥以传统的 PEM 私钥格式存储。这也是提及作为 OpenSSL 的 PEM 格式。

很快就能注意到的区别是在标题标签中。-m PKCS8产生:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

尽管-m PEM

-----BEGIN RSA PUBLIC KEY-----
...
-----END RSA PUBLIC KEY-----

值得一提的是,拟议标准 RFC8301状态那:

签名者必须对所有密钥使用至少 1024 位的 RSA 密钥。签名者应使用至少 2048 位的 RSA 密钥。

同时还认识“应有”方法的实际局限性:

广泛使用的 DNS 配置软件对密钥大小设置了实际限制,因为该软件仅处理 TXT 记录中的单个 256 八位字节字符串,而长度明显超过 1024 位的 RSA 密钥无法容纳在 256 个八位字节中。

因此,如果适用的话,应该使用具有推荐位长度的方法:

# generates a pair
ssh-keygen -t rsa -b 2048 -f sample

# converts the public key into the `PKCS #8`
ssh-keygen -f sample.pub -m PKCS8 -e > sample.pub.pem

相关内容