在Java中生成X509Certificate的主题哈希 [英] Generate Subject Hash of X509Certificate in Java
问题描述
我目前正在尝试使用Java安全API和BouncyCastle来生成主题散列。
以下是我在使用Openssl Library时的操作:
openssl x509 -in /Users/Sn0wfreezeDev/Downloads/Test.pem -hash
这会产生一个短8位数散列 1817886a
这是我的Java代码
X509Certificate cert = CertManager.getCertificate(number,c);
MessageDigest sha1 = MessageDigest.getInstance(SHA1);
System.out.println(Subject+ cert.getSubjectDN());
System.out.println(Issuer+ cert.getIssuerDN());
sha1.update(cert.getSubjectDN()。getName()。getBytes());
String hexString = bytesToHex(sha1.digest());
System.out.println(sha1+ hexString);
System.out.println();
8位数字散列1817886a
来自OpenSSL的这种形式有两种:
$ cd openssl-1.0.2-src
$ grep -R X509_subject_name_hash *
...
crypto / x509 / x509.h:unsigned long X509_subject_name_hash(X509 * x);
crypto / x509 / x509.h:unsigned long X509_subject_name_hash_old(X509 * x);
crypto / x509 / x509_cmp.c:unsigned long X509_subject_name_hash(X509 * x)
crypto / x509 / x509_cmp.c:unsigned long X509_subject_name_hash_old(X509 * x)
...
生成X509Certificate的Subject Hash Java ...
以下是它们的来源: crypto / x509 / x509_cmp.c
$ b $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $' X-> cert_info->受试者));
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_subject_name_hash_old(X509 * x)
{
return(X509_NAME_hash_old(x-> cert_info-> subject ));
}
#endif
最后:
unsigned long X509_NAME_hash(X509_NAME * x)
{
unsigned long ret = 0;
unsigned char md [SHA_DIGEST_LENGTH];
$ b $ *确保X509_NAME结构包含有效的缓存编码* /
i2d_X509_NAME(x,NULL);
if(!EVP_Digest(x-> canon_enc,x-> canon_enclen,md,NULL,EVP_sha1(),
NULL))
return 0; ((无符号长整数)md [0])|((无符号长整数)md [1] <8L)|
((无符号长整数)md [2] ]( )& 0xffffffffL;
return(ret);
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_NAME_hash_old(X509_NAME * x)
{
EVP_MD_CTX md_ctx;
unsigned long ret = 0;
unsigned char md [16];
$ b $ *确保X509_NAME结构包含有效的缓存编码* /
i2d_X509_NAME(x,NULL);
EVP_MD_CTX_init(& md_ctx);
EVP_MD_CTX_set_flags(& md_ctx,EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); (& md_ctx,EVP_md5(),NULL)
&&& EVP_DigestUpdate(& md_ctx,x->字节 - >数据,x->字节 - > ((无符号长整数)md [0])|((无符号长整数)md [1]< b&& mP_DigestFinal_ex(& md_ctx,md,NULL) < 8L)|
((无符号长)md [2] <<< 16L)|((无符号长)md [3] <24L) 0xffffffffL;
EVP_MD_CTX_cleanup(& md_ctx);
return(ret);
}
#endif
i2d_X509_NAME
编码一个 X509_NAME
使用 RFC 2459 (和别处)。例如,它用于证书主题和发行者名称。
您可以看到OpenSSL使用的命名字符串如 openssl x509 - 在< cert> -text -noout
。它看起来类似于 C = US,ST =加州,L = Mountain View,O = Google Inc,CN = www.google.com
(取自Google证书) 。
在Java中生成X509Certificate的主题哈希...
在大图中,您正在生成Subject的可分辨名称字符串的散列并返回一个无符号长整数。 unsigned long实际上是一个截断的散列。
X509_subject_name_hash
使用SHA-1, X509_subject_name_hash_old
使用MD5。
(comment)...他们如何使用sha1散列来生成短散列
OpenSSL提供了截断散列的十六进制编码。整个散列在 md
中。 md
将是16个字节(MD5)或20个字节(SHA-1)。
截断发生在字节 [0,3]
和位于 md [0]
, md [1]
, md [2]
和 md [3]
p>
8位数字来自十六进制编码的4个字节。
I'm currently trying to generate the subject hash by using the Java Security API and BouncyCastle.
Here's what I do, when I use the Openssl Library:
openssl x509 -in /Users/Sn0wfreezeDev/Downloads/Test.pem -hash
This generates a short 8 digit hash 1817886a
This is my Java code
X509Certificate cert = CertManager.getCertificate(number, c);
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
System.out.println(" Subject " + cert.getSubjectDN());
System.out.println(" Issuer " + cert.getIssuerDN());
sha1.update(cert.getSubjectDN().getName().getBytes());
String hexString = bytesToHex(sha1.digest());
System.out.println(" sha1 " + hexString);
System.out.println();
This generates a short 8 digit hash 1817886a
There are two forms of this from OpenSSL:
$ cd openssl-1.0.2-src
$ grep -R X509_subject_name_hash *
...
crypto/x509/x509.h:unsigned long X509_subject_name_hash(X509 *x);
crypto/x509/x509.h:unsigned long X509_subject_name_hash_old(X509 *x);
crypto/x509/x509_cmp.c:unsigned long X509_subject_name_hash(X509 *x)
crypto/x509/x509_cmp.c:unsigned long X509_subject_name_hash_old(X509 *x)
...
Generate Subject Hash of X509Certificate in Java...
Here is the source for them from crypto/x509/x509_cmp.c
:
unsigned long X509_subject_name_hash(X509 *x)
{
return (X509_NAME_hash(x->cert_info->subject));
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_subject_name_hash_old(X509 *x)
{
return (X509_NAME_hash_old(x->cert_info->subject));
}
#endif
And finally:
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);
}
#ifndef OPENSSL_NO_MD5
unsigned long X509_NAME_hash_old(X509_NAME *x)
{
EVP_MD_CTX md_ctx;
unsigned long ret = 0;
unsigned char md[16];
/* Make sure X509_NAME structure contains valid cached encoding */
i2d_X509_NAME(x, NULL);
EVP_MD_CTX_init(&md_ctx);
EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL)
&& EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length)
&& EVP_DigestFinal_ex(&md_ctx, md, NULL))
ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) |
((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L)
) & 0xffffffffL;
EVP_MD_CTX_cleanup(&md_ctx);
return (ret);
}
#endif
i2d_X509_NAME
encodes a X509_NAME
into a standard representation using RFC 2459 (and elsewhere). Its used, for example, in certificate subject and issuer names.
You can see what OpenSSL uses for the name string with commands like openssl x509 -in <cert> -text -noout
. It will look similar to C=US, ST=California, L=Mountain View, O=Google Inc, CN=www.google.com
(taken from a Google certificate).
Generate Subject Hash of X509Certificate in Java...
In the big picture, you are generating a hash of the Subject's Distinguished Name string and returning an unsigned long. The unsigned long is effectively a truncated hash.
X509_subject_name_hash
uses SHA-1, and X509_subject_name_hash_old
uses MD5.
(comment) ... how they can use a sha1 hash to generate that short hash
OpenSSL provides a hex encoding of a truncated hash. The whole hash is in md
. md
will be 16 bytes (MD5) or 20 bytes (SHA-1).
The truncation occurs with the selection of bytes [0,3]
and the bit operations on md[0]
, md[1]
, md[2]
and md[3]
.
The 8 digits comes from hex encoding the 4 bytes.
这篇关于在Java中生成X509Certificate的主题哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!