除了 ssh 和 sshd,OpenSSH 还附带 ssh-keygen:它能生成和转换密钥,并能通过 -Y sign 为文件和 git 提交生成 SSHSIG 签名。本页的事实基于 Alpine 3.24.2 的软件包 OpenSSH 10.3p1 检查得出,它链接的是镜像中的 OpenSSL 3.5.8。不带 -t 时,ssh-keygen 生成 Ed25519 密钥。ECDSA 密钥只支持 P-256、P-384 和 P-521(-b 224 会被拒绝),没有 Ed448,DSA 也已移除:ssh-keygen -t dsa 会报错“unknown key type dsa”。可以用 SSH 公钥查看器查看任意密钥。
没有配置文件时,客户端首先提供混合密钥交换 mlkem768x25519-sha256,其次是 sntrup761x25519-sha512——为会话密钥提供后量子保护。ssh -Q sig 没有列出任何后量子签名算法,因此主机和用户的身份验证仍采用传统算法。使用 SHA-1 的 RSA(ssh-rsa)仍然有实现,但不在默认的主机密钥算法列表和公钥算法列表中,因此在默认设置下客户端从不使用它;如果对端只提供 ssh-rsa 而没有更新的算法,就需要显式地重新启用它,例如对用户密钥使用 PubkeyAcceptedAlgorithms +ssh-rsa。可以用 SSH 服务器审计检查服务器协商的结果。
SSH 中的 ECDSA 签名既不是 DER,也不是原始 r‖s:签名数据块是字符串 ecdsa-sha2-nistp256,后接一个以 SSH mpint 形式存放 r 和 s 的字符串(RFC 5656)。因此,把签名转换为 X.509、JWS 或 WebAuthn 所用的格式,或者反向转换,都意味着要重新编码这两个整数。nonce 是随机的——同一文件的两个签名不同——s 没有经过规范化,把 s 替换为 n − s 的签名也能验证通过。
SSHSIG 签名(ssh-keygen -Y sign)默认用 SHA-512 对消息计算哈希;-O hashalg=sha256 是唯一的替代选项,SHA-1 和 SHA-384 会被拒绝。用 -n 指定的命名空间是签名内容的一部分,把 file 签名按 email 验证会报错“namespace does not match”。失败原因可以在 stderr 上区分——数据块损坏时为“invalid format”,针对其他数据的有效签名为“incorrect signature”——而 stdout 在两种情况下都输出“Could not verify signature.”。可以用 SSH 签名验证工具检查签名。
ssh-keygen -e -m PKCS8 把公钥导出为 SPKI PEM,-i -m PKCS8 再把它导入回来;-m PEM 对 ECDSA 同样输出 SPKI,对 RSA 则输出 PKCS#1;-m RFC4716 输出“SSH2 PUBLIC KEY”格式。Ed25519 公钥无法用 -e -m PKCS8 导出(“unsupported key type ED25519”),不过 -p -m PKCS8 可以把 Ed25519 私钥改写为 PKCS#8。私钥默认以 OPENSSH PRIVATE KEY 格式保存;-p -m PEM 把 ECDSA 密钥改写为 SEC1、把 RSA 密钥改写为 PKCS#1,而带口令的 -m PKCS8 会写出加密的 PKCS#8。