Trần Minh Quân
Trần Minh Quân

Reputation: 29

How to Valid OpenSSH public key format by Java before importing key pair on AWS?

My task is using Java to validate OpenSSH Public key(RSA key) which will be supported on AWS.

Example, I have two RSA format, how can I validate them by Java?

    ---- BEGIN PUBLIC KEY ----
Comment: "4096-bit RSA, converted from OpenSSH by dhopson@VMUbuntu-DSH"
AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o
39jSkHNiMMER/GETBbzP83LOcekm02aRjo55ArO7gPPVvCXbrirJu9pkm4AC4BBre5xSLS
7soyzwbigFruM8G63jSXqpHqJ/ooi168sKMC2b0Ncsi+JlTfNYlDXJVLKEeZgZOInQyMmt
isaDTUQWTIv1snAizf4iIYENuAkGYGNCL77u5Y5VOu5eQipvFajTnps9QvUx/zdSFYn9e2
sulWM3Bxc/S4IJ67JWHVRpfJxGi3hinRBH8WQdXuUwdJJTiJHKPyYrrM7Q6Xq4TOMFtcRu
LDC6u3BXM1L0gBvHPNOnD5l2Lp5EjUkQ9CBf2j4A4gfH+iWQZyk08esAG/iwArAVxkl368
+dkbMWOXL8BN4x5zYgdzoeypQZZ2RKH780MCTSo4WQ19DP8pw+9q3bSFC9H3xYAxrKAJNW
jeTUJOTrTe+mWXXU770gYyQTxa2ycnYrlZucn1S3vsvn6eq7NZZ8NRbyv1n15Ocg+nHK4f
uKOrwPhU3NbKQwtjb0Wsxx1gAmQqIOLTpAdsrAauPxC7TPYA5qQVCphvimKuhQM/1gMV22
5JrnjspVlthCzuFYUjXOKC3wxz6FFEtwnXu3uC5bVVkmkNadJmD21gD23yk4BraGXVYpRM
IB+X+OTUUI8=
---- END PUBLIC KEY ----

    ssh-rsa
AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o
39jSkHNiMMER/GETBbzP83LOcekm02aRjo55ArO7gPPVvCXbrirJu9pkm4AC4BBre5xSLS
7soyzwbigFruM8G63jSXqpHqJ/ooi168sKMC2b0Ncsi+JlTfNYlDXJVLKEeZgZOInQyMmt
isaDTUQWTIv1snAizf4iIYENuAkGYGNCL77u5Y5VOu5eQipvFajTnps9QvUx/zdSFYn9e2
sulWM3Bxc/S4IJ67JWHVRpfJxGi3hinRBH8WQdXuUwdJJTiJHKPyYrrM7Q6Xq4TOMFtcRu
LDC6u3BXM1L0gBvHPNOnD5l2Lp5EjUkQ9CBf2j4A4gfH+iWQZyk08esAG/iwArAVxkl368
+dkbMWOXL8BN4x5zYgdzoeypQZZ2RKH780MCTSo4WQ19DP8pw+9q3bSFC9H3xYAxrKAJNW
jeTUJOTrTe+mWXXU770gYyQTxa2ycnYrlZucn1S3vsvn6eq7NZZ8NRbyv1n15Ocg+nHK4f
uKOrwPhU3NbKQwtjb0Wsxx1gAmQqIOLTpAdsrAauPxC7TPYA5qQVCphvimKuhQM/1gMV22
5JrnjspVlthCzuFYUjXOKC3wxz6FFEtwnXu3uC5bVVkmkNadJmD21gD23yk4BraGXVYpRM
IB+X+OTUUI8= dhopson@VMUbuntu-DSH

Upvotes: 1

Views: 1000

Answers (1)

neubert
neubert

Reputation: 16792

This'll decode an OpenSSH formatted key assuming you remove the "ssh-rsa " bit from the beginning and the comment (" dhopson@VMUbuntu-DSH") from the end:

import java.util.Base64; 
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.lang.UnsupportedOperationException;
import javax.xml.bind.DatatypeConverter;
import java.math.BigInteger;

public class Demo
{
    public static void main(String[] args)
    {
        String key = "AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o" +
"39jSkHNiMMER/GETBbzP83LOcekm02aRjo55ArO7gPPVvCXbrirJu9pkm4AC4BBre5xSLS" +
"7soyzwbigFruM8G63jSXqpHqJ/ooi168sKMC2b0Ncsi+JlTfNYlDXJVLKEeZgZOInQyMmt" +
"isaDTUQWTIv1snAizf4iIYENuAkGYGNCL77u5Y5VOu5eQipvFajTnps9QvUx/zdSFYn9e2" +
"sulWM3Bxc/S4IJ67JWHVRpfJxGi3hinRBH8WQdXuUwdJJTiJHKPyYrrM7Q6Xq4TOMFtcRu" +
"LDC6u3BXM1L0gBvHPNOnD5l2Lp5EjUkQ9CBf2j4A4gfH+iWQZyk08esAG/iwArAVxkl368" +
"+dkbMWOXL8BN4x5zYgdzoeypQZZ2RKH780MCTSo4WQ19DP8pw+9q3bSFC9H3xYAxrKAJNW" +
"jeTUJOTrTe+mWXXU770gYyQTxa2ycnYrlZucn1S3vsvn6eq7NZZ8NRbyv1n15Ocg+nHK4f" +
"uKOrwPhU3NbKQwtjb0Wsxx1gAmQqIOLTpAdsrAauPxC7TPYA5qQVCphvimKuhQM/1gMV22" +
"5JrnjspVlthCzuFYUjXOKC3wxz6FFEtwnXu3uC5bVVkmkNadJmD21gD23yk4BraGXVYpRM" +
"IB+X+OTUUI8=";
                
        byte[] keyBytes = Base64.getDecoder().decode(key);
        int offset = 4;
        int length;
        BigInteger publicExponent, modulus;

        length = ByteBuffer.wrap(Arrays.copyOfRange(keyBytes, 0, 4)).getInt();

        byte[] keyType = Arrays.copyOfRange(keyBytes, 4, 4 + length);
        if (!Arrays.equals(keyType, "ssh-rsa".getBytes())) {
            throw new UnsupportedOperationException(
                DatatypeConverter.printHexBinary("ssh-rsa".getBytes()) +
                " key expected - got " +
                DatatypeConverter.printHexBinary(keyType)
            );
        }
        offset+= length;
        length = ByteBuffer.wrap(Arrays.copyOfRange(keyBytes, offset, offset + 4)).getInt();
        offset+= 4;
        publicExponent = new BigInteger(Arrays.copyOfRange(keyBytes, offset, offset + length));
        offset+= length;
        length = ByteBuffer.wrap(Arrays.copyOfRange(keyBytes, offset, offset + 4)).getInt();
        offset+= 4;
        modulus = new BigInteger(Arrays.copyOfRange(keyBytes, offset, offset + length));

        System.out.println(publicExponent.toString());
        System.out.println(modulus.toString());
    }
}

The fact that it decodes an OpenSSH key means that it should be sufficient to validate it.

If the decoding fails at any point an exception will be thrown. Like Arrays.copyOfRange() will throw ArrayIndexOutOfBoundsException if there's not enough binary data.

ie. if no exception is thrown than the key is good. If an exception is thrown then the key is bad.

Upvotes: 3

Related Questions