如何从Java中的SSH RSA公钥计算指纹?

linc01n:

作为标题,如何从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==

dave_thompson_085:

您的主要问题是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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章