java - 证书的 base32 编码散列不匹配

标签 java android hash certificate guava

Syncthing使用以下 Go 代码计算“节点 ID”,即 SSL 证书的 base32 编码 SHA256 哈希值:

func certID(bs []byte) string {
    hf := sha256.New()
    hf.Write(bs)
    id := hf.Sum(nil)
    return strings.Trim(base32.StdEncoding.EncodeToString(id), "=")
}

据我所知,证书是 just passed in作为原始字节:

 // ...
    remoteID := certID(certs[0].Raw)
 // ...

我尝试使用以下方法在 Java 中复制它(我对 Java 有点陌生):

public static String ComputeSTNodeID(Certificate cert) {
    MessageDigest md = MessageDigest.getInstance("SHA256");
    return BaseEncoding.base32().encode(md.digest(cert.getEncoded())).replaceAll("=", "");
}

(BaseEncoding 是从 Google 的 Guava 库中借用的。)

对于给定的证书,计算是不同的:

Go:   T2JOFPRO7UJB4YHXOSCY4U4YQEFLFI355JQKRD7ZB2ZLEPU6RD4Q
Java: HMKJKSJPB7CM54YHMYIFAN5F7MZAHOFXX4XG5SQWAZLY4I4ROJFA

我做错了什么? @fge 和我发现 .getEncoded() 调用返回的内容与 Go .Raw 成员中包含的内容不同。

最佳答案

这并不是一个完整的答案,但使用 Guava 可以让您的生活更轻松,方法是使用 Hasher 而不是 MessageDigest

为什么?因为Hasher扩展了PrimitiveSink,这意味着你可以为Certificate创建一个Funnel;您只需更改 Funnel 即可使该部分正确!

插图:

public enum CertificateFunnel
    implements Funnel<Certificate>
{
    INSTANCE
    {
        @Override
        public void funnel(final Certificate from, final PrimitiveSink into)
        {
            into.putBytes(from.getEncoded());
        }
    }
}

然后您将拥有一个private static final HashFunction SHA256:

private static final HashFunction SHA256 = Hashing.sha256();

还有一个 private static final BaseEncoding BASE32_NOPAD 因为 BaseEncoding 的实例是线程安全且不可变的:

private static final BaseEncoding BASE32_NOPAD
    = BaseEncoding.base32().omitPadding(); // No need to strip `=`!

然后您将向证书提供:

final Hasher hasher = SHA256.newHasher();

// Funnel the certificate...
hasher.putObject(certificate, CertificateFunnel.INSTANCE);

// Then encode
return BASE32_NOPAD.encode(hasher.hashCode().asBytes());

只是我的 .02 比特币。

关于java - 证书的 base32 编码散列不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23670452/

相关文章:

java - 在 Selenium Webdriver 中处理多页表

用于编辑文档属性的 Java 库

java - 在特定表中查找字符串

java - 我想从数据库获取数据并用数组检查它,但它不起作用

Android 插件安装错误。操作无法完成

java - Android - 无法实例化以下类

android - 如何在 zoom android 中应用长按和捏合?

sql-server-2008 - SQL Server 2008 和 HashBytes

c# - JavaScript 哈希和等效的 .NET 算法

c - C 中的哈希表不适用于字符串