Convert OpenSSH Private Key to OpenSSL Private Key in Java

In 2019, I answered a question on StackOverflow on converting an OpenSSH Private Key to an RSA Private Key. Recently, I had an inquiry about this, so I thought it would be helpful to document for others the exact steps required to perform the conversion in Java using the Maverick Synergy Java SSH API.

https://stackoverflow.com/questions/56900615/how-to-convert-openssh-private-key-to-rsa-private-key-in-java

Let’s start by generating a strong, encrypted OpenSSH RSA Private Key.

ssh-keygen -t rsa -b 3072

Provide a passphrase when prompted, and remember to replace this in the code below. We will use “passphrase” in our examples for ease of use.

First, we need some specific dependencies in the Maverick Synergy environment. I won’t review how to set up the environment here; our website has many examples.

Ensure you have the maverick-bc module as part of your dependencies. If you are using Maven, then use the dependency below.

<dependency>
      <groupId>com.sshtools</groupId>
      <artifactId>maverick-bc</artifactId>
      <version>3.0.9-SNAPSHOT</version>
 </dependency>

Before you call any Maverick API, set the BouncyCastle provider using the code:

JCEProvider.enableBouncyCastle(false);

This statement ensures that the API uses BouncyCastle. Including the BouncyCastle API on the classpath is not enough, as there are some pre-configurations the API has to perform on its default setup to utilise BouncyCastle correctly. 

Next, we load the OpenSSH key into our program.

SshKeyPair pair = SshKeyUtils.getPrivateKey(new File("id_rsa"), "passphrase");

The SshKeyPair object now holds the unencrypted private and public key information. From here, we can convert it to another format. No public API performs this, so we have to use some API classes directly. 

System.out.write(new OpenSSHPrivateKeyFileBC(pair, "passphrase").getFormattedKey());

We can use the OpenSSHPrivateKeyFileBC class to output a formatted key in an OpenSSL format. Before you start writing in, the class name does not correctly reflect what it does and will change in a future version.

If you want to reverse this operation, if you have enabled BouncyCastle correctly, the getPrivateKey of SshKeyUtils method will load the OpenSSL RSA key. You can reverse this back to OpenSSH format using.

SshKeyUtils.savePrivateKey(pair, "passphrase", "Some Comment", new File("id_rsa"));