sshで使用されるキー形式は、RFC#4253で定義されています。RSA公開鍵の形式は次のとおりです。
string "ssh-rsa"
mpint e /* key public exponent */
mpint n /* key modulus */
すべてのデータ型エンコーディングは、RFC#4251のセクション#5で定義されています。文字列型と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でエンコードするだけです。
秘密鍵エンコーディングには、次の2つのケースがあります。
- 秘密鍵はパスワードで保護されていません。その場合、秘密鍵はPKCS#8標準に従ってエンコードされ、Base64でエンコードされます。を呼び出すことにより、秘密鍵のPKCS8エンコーディングを取得することができ
getEncoded
ますRSAPrivateKey
。
- 秘密鍵はパスワードで保護されています。その場合、キーエンコーディングはOpenSSH専用フォーマットです。この形式に関するドキュメントがあるかどうかはわかりません(もちろんOpenSSHソースコードを除く)