如何从Java中的SSH RSA公钥计算指纹? [英] How to Calculate Fingerprint From SSH RSA Public Key in Java?

查看:283
本文介绍了如何从Java中的SSH RSA公钥计算指纹?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As title, How to Calculate Fingerprint From SSH RSA Public Key in Java? I got an rsaPublicKey object from sample.pub and I calculated the fingerprint by using library Apache Commons Codec DigestUtils.sha256Hex(rsaPublicKey.getEncoded()); But I got a different fingerprint when using ssh-keygen command ssh-keygen -E sha256 -lf sample.pub sample.pub as below ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAQEAsuVPKUpLYSCNVIHD+e6u81IUznkDoiOvn/t56DRcutRc4OrNsZZ+Lmq49T4JCxUSmaT8PeLGS/IC946CNQzFwMh++sVoc19UUkZtRaDgiYn+HkYk8VW4IFI1dKfXomKSbX/lB+ohzLzXLVP2/UJgfBmdaE10k+6b+/Yd8YGXIeS8/Z9zToHPo0ORNSGIolgq3xMXUtfAOK/0KC6IFc/FuvuOSAG1UWup91bcm5GSXv4BWWjgFtOxCLIknYjsDah4qfrP8Olp5eUDhn/65xRcZsmRXoYe1ylhlSjJoPDFWXVs9npwqQmi3JaZtgg7xJxMu1ZcdpYxoj280zM9/6w1Lw==

推荐答案

您的主要问题是,SSH用于公钥的 XDR样式编码不是OpenSSH用于计算指纹的公钥.与Java加密所使用的编码相同,这是X.509正式定义为SubjectPublicKeyInfo的ASN.1 DER格式.实际上,我很惊讶您能够用Java读取OpenSSH .pub文件.没有直接的方法可以这样做.在 ssh-keygen和openssl给出两个现有的Q不同的公共密钥(公开:我的),但快速检查一下,我认为它们都不是Java,因此您需要执行以下操作:

Your main problem is that the XDR-style encoding used by SSH for publickey, which OpenSSH uses to compute the fingerprint, is not the same as the encoding used by Java crypto, which is an ASN.1 DER format defined by X.509 formally called SubjectPublicKeyInfo. In fact I'm very surprised you were able to read an OpenSSH .pub file in Java; there is no direct way to do so. See numerous existing Qs on this at ssh-keygen and openssl gives two different public keys (disclosure: mine) but on a quick check I don't think any of them are Java so you'll need to do something like:

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捕获了该错误-我会尝试始终在发布之前进行编译,但不确定如何错过此代码.)

(Aside: Thanks linc01n for catching the bug -- I try to always compile before posting and I'm not sure how I missed this one.)

第二个问题是 OpenSSH 从未以十六进制显示SHA256指纹.它最初在带有冒号的十六进制中使用了 MD5 指纹;在6.8中,默认情况下它会切换为 base64中的 SHA256 (使用传统字母而不是JSON首选的"URLsafe"),尽管您仍然可以获得较旧的格式(在ssh中使用-oFingerprintHash=md5或等效的配置设置;在ssh-keygen -l中使用-E md5).确定您想要的一个并进行相应的编码.

The second problem is that OpenSSH has never displayed SHA256 fingerprints in hex. It originally used MD5 fingerprints in hex with colons; in 6.8 it switched by default to SHA256 in base64 (using the traditional alphabet not the 'URLsafe' one preferred by JSON) although you can still get the older form (in ssh use -oFingerprintHash=md5 or the equivalent config setting; in ssh-keygen -l use -E md5). Determine which one(s?) you want and code accordingly.

或者,如果您拥有.pub文件,只需读取一行的第二个以空格分隔的字段,从base64转换为byte[],对其进行哈希处理并显示.

Or, if you have the .pub file, just read the second space-separated field of the one line, convert from base64 to byte[], hash that, and display.

这篇关于如何从Java中的SSH RSA公钥计算指纹?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆