在AWS上导入密钥对之前,如何通过Java验证OpenSSH公钥格式?

在AWS上导入密钥对之前,如何通过Java验证OpenSSH公钥格式?,java,ssh,rsa,ssh-keys,openssh,Java,Ssh,Rsa,Ssh Keys,Openssh,我的任务是使用Java验证AWS将支持的OpenSSH公钥(RSA密钥) 例如,我有两种RSA格式,如何用Java验证它们 ---- BEGIN PUBLIC KEY ---- Comment: "4096-bit RSA, converted from OpenSSH by dhopson@VMUbuntu-DSH" AAAAB3NzaC1yc2EAAAABIwAAAgEAwrr66r8n6B8Y0zMF3dOpXEapIQD9DiYQ6D6/zwor9o 39jS

我的任务是使用Java验证AWS将支持的OpenSSH公钥(RSA密钥)

例如,我有两种RSA格式,如何用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”位和注释(“dhopson@VMUbuntu-DSH”)从末尾开始:

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());
    }
}
它解码OpenSSH密钥的事实意味着它应该足以验证它

如果解码在任何点失败,将引发异常。如
Arrays。如果没有足够的二进制数据,copyOfRange()
将抛出
ArrayIndexOutOfBoundsException


如果没有抛出异常,则密钥是好的。如果引发异常,则密钥无效。

这些密钥是相同的,并且是ssh格式。带有“-----开始公钥----”的密钥应采用不同的格式,即RFC 5280中指定的SubjectPublicKeyInfo ASN.1结构。在这种情况下,不清楚您所说的“有效”或“验证”是什么意思。
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());
    }
}