作为标题,如何从Java中的SSH RSA公钥计算指纹?我从sample.pub获得了一个rsaPublicKey对象,并使用库Apache Commons Codec计算了指纹, DigestUtils.sha256Hex(rsaPublicKey.getEncoded());
但是使用ssh-keygen命令 ssh-keygen -E sha256 -lf sample.pub
sample.pub 时却得到了不同的指纹,如下所示 ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAsuVPKUpLYSCNVIHD+e6u81IUznkDoiOvn/t56DRcutRc4OrNsZZ+Lmq49T4JCxUSmaT8PeLGS/IC946CNQzFwMh++sVoc19UUkZtRaDgiYn+HkYk8VW4IFI1dKfXomKSbX/lB+ohzLzXLVP2/UJgfBmdaE10k+6b+/Yd8YGXIeS8/Z9zToHPo0ORNSGIolgq3xMXUtfAOK/0KC6IFc/FuvuOSAG1UWup91bcm5GSXv4BWWjgFtOxCLIknYjsDah4qfrP8Olp5eUDhn/65xRcZsmRXoYe1ylhlSjJoPDFWXVs9npwqQmi3JaZtgg7xJxMu1ZcdpYxoj280zM9/6w1Lw==
您的主要问题是SSH用于公钥的XDR样式编码(OpenSSH用于计算指纹)与Java加密所使用的编码不同,Java加密是X.509正式定义的ASN.1 DER格式叫SubjectPublicKeyInfo
。实际上,我为您能够.pub
用Java 读取OpenSSH 文件感到非常惊讶。没有直接的方法可以这样做。在ssh-keygen上可以看到许多现有的Q ,openssl提供了两个不同的公钥(公开:我的),但是快速检查一下,我认为它们都不是Java,因此您需要执行以下操作:
byte[] n = rsapubkey.getModulus().toByteArray(); // Java is 2sC bigendian
byte[] e = rsapubkey.getPublicExponent().toByteArray(); // and so is SSH
byte[] tag = "ssh-rsa".getBytes(); // charset very rarely matters here
ByteArrayOutputStream os = new ByteArrayOutputStream();
DataOutputStream do = new DataOutputStream(os);
do.writeInt(tag.length); do.write(tag);
do.writeInt(e.length); do.write(e);
do.writeInt(n.length); do.write(n);
byte[] encoded = os.toByteArray();
// now hash that (you don't really need Apache)
// assuming SHA256-base64 (see below)
MessageDigest digest = MessageDigest.getInstance("SHA256");
byte[] result = digest.digest(encoded);
String output = Base64.getEncoder().encodeToString(result);
(此外:感谢linc01n捕获了该错误-我会尝试始终在发布前进行编译,但不确定如何错过此错误。)
第二个问题是OpenSSH从未以十六进制显示SHA256指纹。它最初在带有冒号的十六进制中使用MD5指纹。在6.8中,默认情况下它会在base64中切换为SHA256(使用传统字母而不是JSON首选的“ URLsafe”),尽管您仍然可以获得较旧的格式(ssh
使用中-oFingerprintHash=md5
或等效的配置设置;ssh-keygen -l
使用中-E md5
)。确定您要的那个并进行相应的编码。
或者,如果您有.pub
文件,则只需读取一行的第二个以空格分隔的字段,然后将base64转换为byte[]
,对其进行哈希处理并显示。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句