在Java中生成X509Certificate的主题哈希 [英] Generate Subject Hash of X509Certificate in Java

查看:485
本文介绍了在Java中生成X509Certificate的主题哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在尝试使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆