使用正则表达式的 ssh-rsa 公钥验证
Posted
技术标签:
【中文标题】使用正则表达式的 ssh-rsa 公钥验证【英文标题】:ssh-rsa public key validation using a regular expression 【发布时间】:2011-01-30 11:15:03 【问题描述】:我可以使用什么正则表达式(如果有)来验证给定的字符串是合法的 ssh rsa 公钥?
我只需要验证实际的密钥 - 我不关心它之前的密钥类型或它之后的用户名注释。
理想情况下,也有人会提供 python 代码来运行正则表达式验证。
谢谢。
【问题讨论】:
正如 David 所指出的,检查字符串是否只包含有效的 Base64 字符是一个开始,但即使这样也不能确保它是一个有效的 SSH 密钥。由于密钥本质上是二进制数据(Base64 格式),我认为正则表达式根本不是验证密钥的合适工具。 你为什么认为你需要这样做? @Callahad - 我想在我的自动系统放入 authorized_keys 文件之前确保它是一个有效的密钥。 另请参阅pypi.python.org/pypi/sshpubkeys 了解验证 ssh-rsa、ssh-dss、ssh-ed25519 和 ecdsa 密钥的 python 包(不仅仅是完整性检查,它实际上包括验证密钥格式和规范合规性)。免责声明:我是作者。 【参考方案1】:“足够好”的检查是查看密钥是否以正确的标题开头。
密钥文件的数据部分应从 base64 解码,否则将失败并返回 base64.binascii.Error
解压前 4 个字节(一个 int),应该是 7。这是 以下字符串的长度(我想这可能会有所不同,但您只关心 ssh-rsa)。
openssh_pubkey = open('keyfile').read()
type, key_string, comment = openssh_pubkey.split()
data = base64.decodestring(key_string)
int_len = 4
str_len = struct.unpack('>I', data[:int_len])[0] # this should return 7
data[int_len:int_len+str_len] == type
或者,您可以放弃二进制检查,并在 ssh-rsa 密钥的开头查找 AAAAB3NzaC1yc2EA
,我仍然会验证它是有效的 base64。
[编辑] 澄清:
通过规范,如果键是长度前缀字符串,则第一部分。长度被打包为一个大端无符号整数('>I' 对于 python 结构)。这里是 7,因为下面的字符串 'ssh-rsa' 有 7 个字节长。 data[4:11]
是接下来的 7 个字节(每个长度前缀),但我编辑了上面的代码以使用一些描述性变量来尝试使其更清晰。如果您想要彻底,您还应该检查 ssh-dss,可能还有 pgp-sign-rsa 和 pgp-sign-dss,但它们并不常见。
【讨论】:
如果我正确理解了您的代码,您正在检查“key_string”是否是一个 base64 可解码序列,然后确保它以 7 开头,因为所有 rsa pubkey 都以 7 开头?data[4:11] == type
是什么意思?【参考方案2】:
根据对“前面的密钥类型”和“后面的用户名注释”的引用,我假设您说的是以 ssh2 密钥文件格式存储的公钥。
在该格式中,密钥以base64 格式存储,因此一个简单的检查就是验证字符串是否仅包含有效的 base64 字符。
如果你想走得更远一点,你可以注意到编码密钥的前几个字节指定了密钥类型,并与之匹配。见this post,上面写着:
如果您对第一个位进行 base64 解码 那个文本(AAAAB3NzaC1yc2EA)你会 发现它以字节 00 00 开头 00 07(表示 7 个字符 字符串紧随其后),然后是七个 字符“ssh-rsa”,这是关键 类型。 DSA 密钥以 略有不同的字符串 'AAAAB3NzaC1kc3MA',解码 类似于字符串“ssh-dss”。
【讨论】:
“类型键注释”布局是openssh格式。 SSH2 格式在 rfc4716 中描述以上是关于使用正则表达式的 ssh-rsa 公钥验证的主要内容,如果未能解决你的问题,请参考以下文章