Generate Subject Hash of X509Certificate in Java

后端 未结 1 1880
迷失自我
迷失自我 2020-12-03 13:01

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:



        
相关标签:
1条回答
  • 2020-12-03 13:52

    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.

    0 讨论(0)
提交回复
热议问题