ssh 使用的密钥格式定义在RFC #4253 http://www.ietf.org/rfc/rfc4253.txt。 RSA 公钥的格式如下:
string "ssh-rsa"
mpint e /* key public exponent */
mpint n /* key modulus */
所有数据类型编码均在第 #5 节中定义RFC #4251 http://www.ietf.org/rfc/rfc4251.txt。 string 和 mpint(多精度整数)类型的编码方式如下:
4-bytes word: data length (unsigned big-endian 32 bits integer)
n bytes : binary representation of the data
例如,字符串“ssh-rsa”的编码是:
byte[] data = new byte[] {0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a'};
对公众进行编码:
public byte[] encodePublicKey(RSAPublicKey key) throws IOException
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
/* encode the "ssh-rsa" string */
byte[] sshrsa = new byte[] {0, 0, 0, 7, 's', 's', 'h', '-', 'r', 's', 'a'};
out.write(sshrsa);
/* Encode the public exponent */
BigInteger e = key.getPublicExponent();
byte[] data = e.toByteArray();
encodeUInt32(data.length, out);
out.write(data);
/* Encode the modulus */
BigInteger m = key.getModulus();
data = m.toByteArray();
encodeUInt32(data.length, out);
out.write(data);
return out.toByteArray();
}
public void encodeUInt32(int value, OutputStream out) throws IOException
{
byte[] tmp = new byte[4];
tmp[0] = (byte)((value >>> 24) & 0xff);
tmp[1] = (byte)((value >>> 16) & 0xff);
tmp[2] = (byte)((value >>> 8) & 0xff);
tmp[3] = (byte)(value & 0xff);
out.write(tmp);
}
要获得密钥的字符串表示,只需将返回的字节数组编码为 Base64 即可。
对于私钥编码有两种情况:
- 私钥不受密码保护。在这种情况下,私钥将根据 PKCS#8 标准进行编码,然后使用 Base64 进行编码。可以通过调用获取私钥的 PKCS8 编码
getEncoded
on RSAPrivateKey
.
- 私钥受密码保护。在这种情况下,密钥编码是 OpenSSH 专用格式。我不知道是否有关于这种格式的任何文档(当然除了OpenSSH源代码)