在 AWS 上导入密钥对之前,如何通过 Java 验证 OpenSSH 公钥格式?
Posted
技术标签:
【中文标题】在 AWS 上导入密钥对之前,如何通过 Java 验证 OpenSSH 公钥格式?【英文标题】:How to Valid OpenSSH public key format by Java before importing key pair on AWS? 【发布时间】:2021-05-05 02:37:12 【问题描述】:我的任务是使用 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
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
【问题讨论】:
这些密钥是相同的并且是 ssh 格式。带有“-----BEGIN PUBLIC KEY----”的密钥预计将采用不同的格式,即 RFC 5280 中指定的 SubjectPublicKeyInfo ASN.1 结构。不清楚您所说的“有效”或“验证”是什么意思" 在这种情况下。 【参考方案1】:假设您从开头删除“ssh-rsa”位并从末尾删除注释(“dhopson@VMUbuntu-DSH”),这将解码 OpenSSH 格式的密钥:
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
。
即。如果没有抛出异常,则密钥是好的。如果抛出异常,则密钥是错误的。
【讨论】:
以上是关于在 AWS 上导入密钥对之前,如何通过 Java 验证 OpenSSH 公钥格式?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 aws-cdk 从 AWS Secrets Manager 导入 EKS 密钥?