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
成员中包含的内容相同的内容。
答案 0 :(得分:2)
这不是一个完整的答案,但使用番石榴,您可以使用Hasher
代替MessageDigest
,让您的生活更轻松。
为什么呢?由于Hasher
扩展了PrimitiveSink
,这意味着您可以为Funnel
创建Certificate
;您只需更改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比特币。