5

I'm doing publicKey.getEncoded(), then appending "ssh-rsa" to the front, then base64 encoding it. Then I add the SSH2 header/footer. But it won't decode...

zigdon
  • 14,573
  • 6
  • 35
  • 54
pizzathehut
  • 113
  • 1
  • 2
  • 5

1 Answers1

19

Java public keys are encoded as a standard X.509 SubjectPublicKeyInfo structure.

SSH2 uses its own simple format. Base-64 encode the result of the encode method shown below, and affix the necessary SSH2 header and footer.

public static byte[] encode(RSAPublicKey key)
  throws IOException
{
  ByteArrayOutputStream buf = new ByteArrayOutputStream();
  byte[] name = "ssh-rsa".getBytes("US-ASCII");
  write(name, buf);
  write(key.getPublicExponent().toByteArray(), buf);
  write(key.getModulus().toByteArray(), buf);
  return buf.toByteArray();
}

private static void write(byte[] str, OutputStream os)
  throws IOException
{
  for (int shift = 24; shift >= 0; shift -= 8)
    os.write((str.length >>> shift) & 0xFF);
  os.write(str);
}

See this answer for converting the other direction, from OpenSSH to Java.

Community
  • 1
  • 1
erickson
  • 265,237
  • 58
  • 395
  • 493
  • Do I need to do something similar if I needed to PEM encode the privatekey? – pizzathehut Aug 27 '10 at 23:14
  • It depends on the application you want to inter-operate with. If you need the key only (not embedded in a certificate) in OpenSSL's format, yes, you need to find out what the format is (probably the modulus and public exponent in a similar format, maybe as an ASN.1 Sequence) and encode it yourself. – erickson Aug 28 '10 at 02:14
  • 2
    Been looking for hours for this code example. THANK YOU! Wish I could gift you a bunch more reputation points. :) – James Ward Oct 31 '11 at 21:04
  • It's possible to do in one or two lines and more generic (support DSA and other types too) with SSHJ: `byte[] b = new Buffer.PlainBuffer().putPublicKey(key).getCompactData()` and then base64-encode it using `Base64.getEncoder().encodeToString(b)`. – Raul Santelices Apr 07 '17 at 22:16
  • @RaulSantelices worked. I just had to add the `ssh-rsa` header to mine. ```return "ssh-rsa " + Base64.getEncoder().encodeToString(b);``` – Aaron Tobias Apr 09 '21 at 22:32