如何从 RSA 公钥计算指纹?
Posted
技术标签:
【中文标题】如何从 RSA 公钥计算指纹?【英文标题】:How to calculate a fingerprint from an RSA public key? 【发布时间】:2021-02-20 07:11:50 【问题描述】:使用此命令可以生成 RSA 公钥-私钥对:
ssh-keygen -f key
现在我想使用模块 cryptography
在 Python 中加载这些键。示例:
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
with open("key.pub", "rb") as f:
datapub = f.read()
public_key = serialization.load_ssh_public_key(datapub, backend=default_backend())
但是现在:如何从这个公钥生成指纹?使用 OpenSSH,这可以使用 ssh-keygen -lf key.pub
来完成。但是你在 Python 中是怎么做到的呢?
【问题讨论】:
AFAIK 没有指纹与RSAPublicKey
实例相关联,例如public_key
。指纹是在格式的上下文中定义的,例如OpenSSH。这里的fingerprint 是 Base64 解码公钥的 SHA256 哈希。一种确定方法是将RSAPublicKey
实例序列化为 OpenSSH 格式,例如使用public_key.public_bytes(...)
(对于发布的示例,这当然会导致datapub
)并确定相应的哈希值,例如with(但使用 SHA256)。
【参考方案1】:
首先:非常感谢 Topaco,您为我提供了如何生成这样一个指纹的基本提示。我与 WWW 上的其他资源进行了交叉核对,无法提供任何人使用的代码。
假设我们已加载密钥并将其存储在public_key
中。那么指纹可以生成如下:
rawKeyData = public_key.public_bytes(
encoding=serialization.Encoding.OpenSSH,
format=serialization.PublicFormat.OpenSSH,
)
# prepare for hashing
m = re.match("ssh-rsa ([A-Za-z0-9+/=]+)", rawKeyData.decode("utf-8"))
assert m is not None
base64BinaryData = m.group(1).encode("utf-8")
rawBinaryData = base64.b64decode(base64BinaryData)
# now create the hash
hexDigest = hashlib.md5(rawBinaryData).hexdigest()
# formatting for output similar to "ssh-keygen -l -E md5 -f <pubkeyfile>"
chunks = [ hexDigest[i:i+2] for i in range(0, len(hexDigest), 2) ]
fingerprint = str(self.__public_key.key_size) + "MD5:" + ":".join(chunks) + " (RSA)"
这提供了这样的输出:
2048 MD5:bd:5a:67:a3:4c:46:9d:2c:63:78:7e:68:bc:82:eb:23 (RSA)
与 OpenSSH 指纹的唯一区别:这里的输出中不包含电子邮件地址。
一些备注:
正则表达式 我在这里使用正则表达式来解析输出。这样做是为了安全,因为这样我可以确保输出符合此处数据处理的预期。 base64 base64 可能会为数据添加填充。 base64 可以安全使用,因为填充是确定性的。 md5 这里使用了 MD5 输出。 如果需要,您可以安全地用任何其他哈希算法替换 MD5 - 例如SHA256。【讨论】:
以上是关于如何从 RSA 公钥计算指纹?的主要内容,如果未能解决你的问题,请参考以下文章
如何从 RSA 公钥 XML 文件 .net core c# 中获取 n 值