簡體   English   中英

用Java生成X509Certificate的主題哈希

[英]Generate Subject Hash of X509Certificate in Java

我目前正在嘗試使用Java安全API和BouncyCastle生成主題哈希。

使用Openssl庫時,這是我的工作:

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)
...

在Java中生成X509Certificate的主題哈希...

這是來自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

最后:

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使用RFC 2459 (和其他地方)將X509_NAME編碼為標准表示形式。 例如,它用於證書主題和頒發者名稱。

您可以使用openssl x509 -in <cert> -text -noout類的命令查看OpenSSL用於名稱字符串的內容。 外觀類似於C=US, ST=California, L=Mountain View, O=Google Inc, CN=www.google.com (摘自Google證書)。


在Java中生成X509Certificate的主題哈希...

在大圖中,您正在生成主題的專有名稱字符串的哈希,並返回無符號的long。 unsigned long實際上是一個截斷的哈希。

X509_subject_name_hash使用SHA-1,而X509_subject_name_hash_old使用MD5。


(評論)...他們如何使用sha1哈希生成短哈希

OpenSSL提供了截斷的哈希的十六進制編碼。 整個哈希在md md將為16個字節(MD5)或20個字節(SHA-1)。

截斷發生在選擇字節[0,3]以及對md[0]md[1]md[2]md[3]

8位數字來自對4個字節進行十六進制編碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM