gpt4 book ai didi

java - 新主题哈希openssl算法不同

转载 作者:搜寻专家 更新时间:2023-11-01 03:24:17 32 4
gpt4 key购买 nike

我在从 Java 框架管理 openssl 证书时遇到问题。

openssl x509 -subject_hash ...

输出与调用 X509_NAME_hash() 时 Java 框架返回的输出不同,见下文。

这是因为 openssl 改变了它计算 SHA1 的方式。现在,它不像 MD5 那样将散列基于主题的 ASN.1 DER 表示,而是首先计算 CANONICAL 表示,然后在此基础上计算 ASN.1 DER,然后将其用作SHA1 算法的输入。

NativeCrypto.java:

// --- X509_NAME -----------------------------------------------------------
public static int X509_NAME_hash(X500Principal principal) {
return X509_NAME_hash(principal, "SHA1");
}

private static int X509_NAME_hash(X500Principal principal, String algorithm) {
try {
byte[] digest = MessageDigest.getInstance(algorithm).digest(principal.getEncoded());
return Memory.peekInt(digest, 0, ByteOrder.LITTLE_ENDIAN);
} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
}
}

我正在研究 openssl 库中的 x_name.cx509_cmp.c 以尝试在 Java 底层修复它。但是我没有成功。

我知道我必须修改 x509_cmp.c 中的 X509_NAME_hash 方法。但不确定该更改应该在 i2d_X509_NAME(x,NULL); 之前还是之后这个方法正在计算主题名称的 CANONICAL 表示,对吗?然后,我需要根据该输出计算 ASN1 DER,对吧?但我就是做不到。

如果有人可以指导我或解决这个问题,我将不胜感激。

x509_cmp.c:

    unsigned long X509_NAME_hash(X509_NAME *x)
{
unsigned long ret=0;
unsigned char md[SHA_DIGEST_LENGTH];

/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x,NULL);
if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(),
NULL))
return 0;

ret=( ((unsigned long)md[0] )|((unsigned long)md[1]<<8L)|
((unsigned long)md[2]<<16L)|((unsigned long)md[3]<<24L)
)&0xffffffffL;
return(ret);
}

x509_name_canon 函数显然执行重新编码。这是在 crypto/asn1/x_name.c 中:

/* This function generates the canonical encoding of the Name structure.
* In it all strings are converted to UTF8, leading, trailing and
* multiple spaces collapsed, converted to lower case and the leading
* SEQUENCE header removed.
*
*/

最佳答案

您离它不远,如果您想要与 OpenSSL new SubjectHash 相同的结果,您必须删除 DN 的前导序列。因此你必须做这样的事情:

// --- X509_NAME -----------------------------------------------------------

public static int X509_NAME_hash(X500Principal principal) {
return X509_NAME_hash(principal, "SHA1");
}

private static int X509_NAME_hash(X500Principal principal, String algorithm) {
try {

byte[] princ = principal.getEncoded();
final ASN1Sequence obj = (ASN1Sequence) ASN1Object.fromByteArray( princ );

// Remove the leading sequence ...
final DERSet enc = (DERSet) obj.getObjectAt(0);
final byte[] toHash = enc.getDEREncoded();

MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(toHash);
return Memory.peekInt(digest, 0, ByteOrder.LITTLE_ENDIAN);

} catch (NoSuchAlgorithmException e) {
throw new AssertionError(e);
} catch (IOException e) {
throw new AssertionError(e);
}
}

结果与 OpenSSL new Subject_hash 相同。

关于java - 新主题哈希openssl算法不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19237167/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com