当前位置: 首页 > 面试题库 >

用Java生成X509Certificate的主题哈希

彭鸿哲
2023-03-14
问题内容

我目前正在尝试使用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_NAMEX509_NAME使用RFC
2459
(及其他地方)将a编码为标准表示形式。例如,它用于证书主题和颁发者名称。

您可以使用类似的命令查看OpenSSL用于名称字符串的内容openssl x509 -in <cert> -text -noout。它看起来类似于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提供了截断的哈希的十六进制编码。整个哈希在中mdmd将为16个字节(MD5)或20个字节(SHA-1)。

截断与字节选择发生[0,3]和对位操作md[0]md[1]md[2]md[3]

8位数字来自对4个字节进行十六进制编码。



 类似资料:
  • 问题内容: 是否有可能从byte []生成java.security.cert.X509Certificate? 问题答案: 当然。 证书对象可以由CertificateFactory的一个实例创建- 尤其是配置为创建X509证书的一个实例。可以这样创建: 然后,您需要向其传递一个包含证书字节的InputStream。这可以通过将字节数组包装在ByteArrayInputStream中来实现:

  • 问题内容: 是否有任何方法可以在Java中生成字符串的MD5哈希? 问题答案: 你需要。 调用以获取你可以使用的MD5实例。 通过执行以下操作之一来计算哈希: 将整个输入作为并使用进行一次运算来计算哈希。 订阅通过调用一次块。添加完输入字节后,请使用计算哈希值 。 在返回的是MD5哈希值。

  • 我正在写一个Django应用程序,需要与现有的Java播放框架应用程序一起工作。Play应用程序使用PasswordHash.java来存储密码。它以冒号分隔的格式存储密码。每个哈希都存储为::。 例如,下面是密码“测试”的条目: 在这里,我们可以通过拆分字符串并找到: 迭代次数: 盐: PBKDF2哈希:。 我修改了Django的check_密码机制以与此格式兼容,但发现它认为密码不正确。我用了

  • 从示例中,我看到了下面的代码片段,它运行良好。但问题是:我并不总是需要处理输入流并将其生成到接收器。 如果我有一个应用程序,根据某些事件,我必须只发布到kafka主题,以便下游应用程序可以做出某些决定。这意味着,我实际上没有输入流,但我只知道当我的应用程序中发生某些事情时,我需要向kafka的特定主题发布消息。也就是说,我只需要一个接收器。 我查看了示例,但没有找到符合我要求的任何内容。有没有一种

  • 这里是源连接器状态的输出: 这里是接收器连接器配置的输出: 这里是接收器连接器状态的输出:

  • 问题内容: 我在htpasswd中使用“密码的强制MD5加密”来生成实例“ 123”的哈希,我得到: 使用htpasswd:123 => $ apr1 $ kaTbKaLO $ ewJXRZAKpjaxK4thy2jOp / 使用MD5摘要:123 => 202cb962ac59075b964b07152d234b70 请告诉我如何使用Java生成像apache htpasswd这样的哈希。 问题