当前位置: 首页 > 知识库问答 >
问题:

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

匡晟
2023-03-14

作为标题,如何在Java中从SSH RSA公钥计算指纹?我从sample.pub获得了一个rsaPublicKey对象,并使用库Apache Commons Codecdigestutils.sha256hex(rsaPublicKey.getEncoded())计算了指纹;但当使用ssh-keygen命令ssh-keygen-e sha256-lf sample.pubsample.pub时,我得到了不同的指纹,如下所示ssh-rsa


共有1个答案

姚麒
2023-03-14

您的主要问题是,SSH对publickey使用的XDR样式编码(OpenSSH用于计算指纹)与Java crypto使用的编码不同,Java crypto是X.509定义的ASN.1 DER格式,正式称为subjectPublicKeyInfo。事实上,我非常惊讶您能够阅读Java版本的OpenSSH.pub文件;没有直接的方法可以这样做。在ssh-keygen和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[],对其进行散列,然后显示。

 类似资料:
  • 我有一个EVP_PKEY结构中的RSA公钥(从PEM文件加载,以------开始公钥------)。现在,我希望能够使用OpenSSL API显示代码中该密钥的指纹。(目的是允许操作员在信任JWT之前使用RS256验证其密钥)。 不幸的是,到目前为止,我发现的所有资源要么在命令行上使用ssh-keygen,要么使用X.509证书的指纹,但不使用公钥。 那么,如何使用OpenSSL API获取存储在

  • 问题内容: 我正在尝试了解采取OpenSSH公钥的步骤,如下所示: SSH-RSA AAAAB3NzaC1yc2EAAAABIwAAAQEAqmEmDTNBC6O8HGCdu0MZ9zLCivDsYSttrrmlq87 / YsEBpvwUTiF3UEQuFLaq5Gm + dtgxJewg / UwsZrDFxzpQhCHB6VmqrbKN2hEIkk / HJvCnAmR1ehXv8n2BWw

  • 从这里我指出了自己如何获得公钥,并使用EC_POINT_bn2point,而不是hex2point,根据OpenSSL源代码,它在内部执行BN_hex2bn。 那么,为什么EC_POINT_bn2point返回null呢?我正在认真考虑重新编译OpenSSL,并放一些调试例程来找出它失败的原因。

  • 我有以下公钥(作为示例): 我需要能够将其转换为可以插入ssh known_hosts文件的格式。例如: 谢了!

  • 以下网站经常被引用,而且我认为是准确的: https://gobittest.appspot.com/Address 我试图在Golang中重现这些步骤,但第一步就失败了:-( 有人能给我提供一个Golang片段,给定ECDSA私钥,返回公钥吗?我想我可能具体指的是上述站点示例中的私钥指数和公钥指数。 i、 例如,给定随机生成的(十六进制编码的)私钥(指数?)<代码>E83385AF76B2B19

  • 我从服务器获得了以下jwks 我有一个加密的令牌。我想用上面的jwk解密它。如何从上述jwk中获取公钥。我从楼梯上走下来https://auth0.com/docs/quickstart/backend/rails/01-authorization.但上述jwk中缺少x5c(证书)。 我想知道在jwk中没有x5c如何获取公钥。