为什么ssh-keygen输出的密钥非32字节?TLS握手密钥使用疑问
问题解答
1. 密钥类型不匹配是长度过长的核心原因
你当前生成的密钥和TLS1.3 Server Hello阶段需要的密钥不属于同一类型:
- 你用
ssh-keygen默认生成的是SSH格式的RSA/ED25519密钥,keytool生成的是RSA格式的证书密钥,这类密钥本身长度就远大于32字节(2048位RSA公钥就有256字节),完全不适用TLS1.3的key_share扩展场景。 - TLS1.3 Server Hello中32字节长度的公钥,是X25519(Curve25519)椭圆曲线密钥交换算法的原始公钥字节,没有任何额外编码头信息。
2. 测试代码输出64字节的原因
你代码中直接对Base64编码的密钥字符串调用getBytes(),拿到的是字符串本身的ASCII编码字节,不是原始密钥字节:
- 你示例中的
MC4CAQAwBQYDK2VuBCIEIJCRkpOUlZaXmJmam5ydnp+goaKjpKWmp6ipqqusra6v是Base64编码的ASN.1 DER格式X25519私钥,包含了密钥类型标识、版本等额外头信息。 - 你需要先对字符串做Base64解码,再从解码后的DER结构中提取最后32字节的原始私钥,再推导得到32字节的原始公钥,即可得到符合要求的公钥。
3. 如何直接生成可用的32字节公钥
使用openssl工具可直接导出无编码的原始X25519公钥:
- 生成X25519私钥文件:
openssl genpkey -algorithm X25519 -out x25519.key
- 导出32字节原始公钥:
openssl pkey -in x25519.key -pubout -outform DER | tail -c 32 > x25519_pub.raw
生成的x25519_pub.raw就是可以直接放到TLS1.3 Server Hello的key_share扩展中使用的32字节公钥。
4. SSH公钥太长的原因
ssh-keygen生成的private.pub是SSH格式的公钥文件,除了原始公钥字节外,还包含了密钥类型标识、用户注释等额外字段,且整体为Base64编码的ASCII文本,因此长度远大于32字节,无法直接用于TLS握手场景,需要额外解码提取原始公钥字节后才能使用。
内容的提问来源于stack exchange,提问作者Jason Rich Darmawan
相关产品推荐
相关产品推荐

