0

I'm trying to dynamically generate a pair of SSH keys in java, mimicking the behaviour of ssh-keygen. I intend to use those keys to communicate with an SSH server.

I have tried patching up and testing several pieces of code without success. The most recent piece of code I'm testing is this:

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.AsymmetricCipherKeyPairGenerator;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.generators.Ed25519KeyPairGenerator;
import org.bouncycastle.crypto.util.OpenSSHPrivateKeyUtil;
import org.bouncycastle.crypto.util.OpenSSHPublicKeyUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.io.pem.PemObject;
import org.bouncycastle.util.io.pem.PemWriter;
import org.junit.jupiter.api.Test;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.security.SecureRandom;
import java.security.Security;

public class GenKeysTest {

    @Test
    void testCase1() throws IOException {
        Security.addProvider(new BouncyCastleProvider());

        AsymmetricCipherKeyPairGenerator gen = new Ed25519KeyPairGenerator();
        gen.init(new KeyGenerationParameters(new SecureRandom(), 255));
        AsymmetricCipherKeyPair keyPair = gen.generateKeyPair();

        byte[] priBytes = OpenSSHPrivateKeyUtil.encodePrivateKey(keyPair.getPrivate());
        write(priBytes, "ed25519", "OPENSSH PRIVATE KEY");

        byte[] pubBytes = OpenSSHPublicKeyUtil.encodePublicKey(keyPair.getPublic());
        write(pubBytes, "ed25519.pub", "OPENSSH PUBLIC KEY");
    }

    public void write(byte[] bytes, String fileName, String type) throws IOException {
        try (FileOutputStream out = new FileOutputStream(fileName)) {
            try (PemWriter w = new PemWriter(new OutputStreamWriter(out))) {
                w.writeObject(new PemObject(type, bytes));
            }
        }
    }
}

I'm using the following dependencies:

dependencies {
    implementation 'org.bouncycastle:bcprov-jdk15on:1.67'
    implementation 'org.bouncycastle:bcpkix-jdk15on:1.67'

    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
}

And I'm using these command to test the resulting keys:

ssh-keygen -l -f ed25519

ssh-keygen -l -f ed25519.pub

As far as I read, those commands should output the same text line which should look like this:

256 SHA256:REDACTED user@domain.com (ED25519)

Instead the output I get from ssh-keygen is similar to this:

ed25519.pub is not a public key file.

It would be very nice if someone could point me what am I missing.

0 Answers0