使用正则表达式验证ssh-rsa公钥

11 投票
2 回答
15245 浏览
提问于 2025-04-15 20:42

我可以用什么样的正则表达式(如果有的话)来验证一个给定的字符串是否是合法的ssh rsa公钥?

我只需要验证实际的公钥部分,不关心它前面的密钥类型或者后面的用户名注释。

最好有人能提供运行这个正则表达式验证的python代码。

谢谢。

2 个回答

2

根据提到的“前面的密钥类型”和“后面的用户名注释”,我猜您是在说以ssh2密钥文件格式存储的公钥。

在这种格式中,密钥是以base64格式存储的,所以一个简单的检查方法就是确认这个字符串只包含有效的base64字符。

如果您想更进一步,可以注意到编码密钥的前几个字节会指定密钥类型,然后进行匹配。可以参考这篇文章,里面提到:

如果你对那段文本的开头部分进行base64解码(AAAAB3NzaC1yc2EA),你会发现它以字节00 00 00 07开头(表示后面跟着一个7个字符的字符串),然后是七个字符“ssh-rsa”,这就是密钥类型。DSA密钥则以稍微不同的字符串AAAAB3NzaC1kc3MA开头,解码后类似于“ssh-dss”。

13

一个“足够好的”检查方法是看看这个密钥是否以正确的开头开始。

密钥文件的数据部分应该是经过base64编码的,如果不是,就会出现base64.binascii.Error的错误。

解压前4个字节(一个整数),它应该是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。

[编辑] 说明:
根据规范,密钥的第一部分是一个带长度前缀的字符串。这个长度是以大端无符号整数的形式存储的(在python结构中用'>I'表示)。这里是7,因为后面的字符串'ssh-rsa'的长度是7个字节。data[4:11]是接下来的7个字节(根据长度前缀),但我在上面的代码中做了一些修改,使用了一些描述性的变量来让这个更清楚。如果你想更全面一点,还应该检查ssh-dss,可能还有pgp-sign-rsa和pgp-sign-dss,但它们相对少见。

撰写回答