背景
在SSH协议中,有两个地方涉及到公钥算法,分别是:
- 服务端认证:服务端在进行密钥协商的时候证明自己身份,防止中间人攻击,此时为SSH-TRANS协议发生的事情;
- 客户端认证:客户端通过PublicKey方式证明自己身份,完成SSH登录认证,此时SSH-USERAUTH发生的事情;
这两种情况下的公钥算法使用的是同一个概念,接下来本文将主要基于PublicKey公钥认证方式,学习对应的内容。
理论知识
公私钥类型
在OpenSSH的ssh-keygen命令中,我们可以通过-t选项来指定我们生成的SSH公私钥对的类型是什么:
类型 | 可选的位数 | 规范 |
---|---|---|
RSA | 1024 2048 3076(default) 4096 |
RFC4253和RFC8332 https://datatracker.ietf.org/doc/html/rfc4253 https://datatracker.ietf.org/doc/html/rfc8332 |
ecdsa | 256(default),nistp256 384, nistp384 521, nistp521 |
RFC5915定义 https://datatracker.ietf.org/doc/html/rfc5915 |
ed25519 | RFC8709 https://www.rfc-editor.org/rfc/rfc8709 |
Public Key Algorithm
在IANA的SSH Parameter列表中,我们可以看到SSH协议使用的Public Key Algorithm Names主要为截图所示:
而在OpenSSH中,通过查看HostKeyAlgorithms(服务端认证时,使用的签名方法)和PubkeyAcceptedAlgorithms(客户端认证时,使用的签名方法),可以找到对应支持的公钥算法具体实现。
结合公私钥类型,我们可以看到,同一个公私钥类型也会支持多种的Public Key Algorithm,以RSA为例,标准定义的算法有三种:ssh-rsa(sha1),rsa-sha2-256,rsa-sha2-512。
Public Key Format
根据RFC8332的解释,Public Key Algorithm和Public Key Format是包含了不同的意思,具体见截图:
根据OpenSSH的实现,目前针对单个SSH公私钥对,我们会遇到如下几个格式(感觉还没有掌握清楚,大家可以具体情况再次分析,我目前使用RSA格式公私钥对进行的转换分析):
key format | 公私钥支持 | 描述 |
---|---|---|
OpenSSH Private format | 公钥、私钥 | OpenSSH ssh-keygen生成的默认格式,对密钥的安全存储做了增强。 |
RFC4716 | 公钥 | RFC4716定义的SSH公钥格式 |
PKCS#8 | 私钥、公钥 | 一般用于存储私钥 |
PEM | 公钥、私钥 | 标准的PEM格式 |
OpenSSH实践
Public Key Format转换
使用ssh-keygen -t rsa命令,我们可以得到如下公钥:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDFmDdF6R+awJS4f5lA8XjOBMJSxDxOMm7....U= localhost
同样,使用ssh-keygen,我们转换公钥为其它格式如下:
ssh-keygen -e -f ssh-rsa.pub -m PEM > ssh-rsa-pem.pub
-----BEGIN RSA PUBLIC KEY-----
MIIBigKCAYEAxZg3RekfmsCUuH+ZQPF4zgTCUsQ8TjJuxUsDE3g6OlCc7h7GtHef
ElJSsVKq1....e59mONPdzH2bxDQpWAP0bU/m48f2oymqgBTP1SnFEMTO1D1
UcESmRWuwmaahTV4QmoY7aq5gLLtiU8hCzYVD7zREUIjPug8oM+htciyyu3qRdvF
sFcUrTe1BrNlAgMBAAE=
-----END RSA PUBLIC KEY-----
ssh-keygen -e -f ssh-rsa.pub -m RFC4716 > ssh-rsa-rfc4716.pub
---- BEGIN SSH2 PUBLIC KEY ----
Comment: "3072-bit RSA, converted by local from OpenSS"
AAAAB3NzaC1yc2EAAAADAQABAAABgQDFmDdF6R+awJS4f5lA8XjOBMJSxDxOMm7FSwMTeD
....
mAsu2JTyELNhUPvNERQiM+6Dygz6G1yLLK7epF28WwVxStN7UGs2U=
---- END SSH2 PUBLIC KEY ----
ssh-keygen -e -f ssh-rsa.pub -m PKCS8 > ssh-rsa-pkcs8.pub
-----BEGIN PUBLIC KEY-----
MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAxZg3RekfmsCUuH+ZQPF4
zgTCUs.....+UXXdKS9jc0Jv1QWiie59mONPdzH2bxDQ
pWAP0bU/m48f2oymqgBTP1SnFEMTO1D1UcESmRWuwmaahTV4QmoY7aq5gLLtiU8h
CzYVD7zREUIjPug8oM+htciyyu3qRdvFsFcUrTe1BrNlAgMBAAE=
-----END PUBLIC KEY-----
指定PubkeyAcceptedAlgorithms
OpenSSH8.8版本以后,默认禁用了ssh-rsa签名方案,这导致我们使用某些老旧客户端时,无法SSH连接上服务器。以Ubuntu22.04为例,通过sshd -T命令,我们可以看到支持Public Key Algorithm如下:
为了模拟使用ssh-rsa签名方案的客户端,我们可以通过如下选项来发起ssh连接:ssh root@xxx.xx.xx.xx -i ssh-rsa -o PubkeyAcceptedAlgorithms=ssh-rsa -v
其最终结果如下所示,公钥认证不通过:
接着我们再指定签名算法为rsa-sha2-256,可以看到认证通过(不指定场景,默认为rsa-sha2-512):ssh root@xx.xx.xx.xx -i ssh-rsa -o PubkeyAcceptedAlgorithms=rsa-sha2-256 -v
总结
本文旨在于理解清楚使用OpenSSH时,涉及到公私钥对格式和签名算法的区别。通过逐步的学习,可以发现SSH公私钥对相关内容主要有如下三点:第一是什么类型的公私钥,如RSA or ECDSA,这里面还可以继续区分对应位数;第二是什么要的编码格式,如OpenSSH格式 or RFC4716格式 or PEM格式;第三是使用什么样的签名的算法,如ssh-rsa(sha1),rsa-sha2-256,rsa-sha2-512。同时针对ssh-rsa这个具体名词,除了签名算法外,在公钥展示时还表示使用了rsa类型的公私钥对,需要注意区分两者的区别。最后,针对签名算法的学习,我们可以通过配置服务端的sshd_config,结合-o PubkeyAcceptedAlgorithms选项来实际验证对应的签名算法使用场景。
参考文档
- IANA SSH Parameter:https://www.iana.org/assignments/ssh-parameters/ssh-parameters.xhtml
- OpenSSH manual Pages:https://www.openssh.com/manual.html
- OpenSSH sshd_config manual Page: https://man.openbsd.org/sshd_config.5#Ciphers
- https://zhuanlan.zhihu.com/p/66794410
- [https: //security.stackexchange.com/questions/270349/understanding-ssh-rsa-not-in-pubkeyacceptedalgorithms]
- https://ubuntu.com/server/docs/openssh-crypto-configuration
- https: //security.stackexchange.com/questions/255074/why-are-rsa-sha2-512-and-rsa-sha2-256-supported-but-not-reported-by-ssh-q-key
- https://www.alibabacloud.com/help/zh/ecs/user-guide/resolve-an-rsa-key-based-connection-failure-to-an-instance
- https://www.rfc-editor.org/rfc/rfc8709
- https://datatracker.ietf.org/doc/html/rfc4253
- https://datatracker.ietf.org/doc/html/rfc8332
- https://datatracker.ietf.org/doc/html/rfc5915