c# - 在 C# 中生成 OpenSSL subject_name 哈希

标签 c# hash openssl

我们正在尝试让主题名称哈希算法在 C# 中运行。您可以使用以下代码从 openssl 命令行运行它。

openssl x509 -inform PEM -hash -noout -in google.pem

这将返回一个 8 字符代码,该代码是证书主题的截断哈希。然而,我们的代码不会返回相同的代码。

public static String GenerateX509SubjectNameHash(X509Certificate xCert)
{
    byte[] bytes = Encoding.ASCII.GetBytes(xCert.SubjectName.Name);
    HashAlgorithm hash = new SHA1Managed();
    var hashBytes = hash.ComputeHash(bytes);
    ulong hashVal = (((ulong)hashBytes[0]) | ((ulong)hashBytes[1] << 8) | ((ulong)hashBytes[2] << 16) | ((ulong)hashBytes[3] << 24) & 0xffffffff);

    return hashVal.ToString("X");
}

可以在此处引用在 openssl 中执行此操作的原始代码:https://github.com/openssl/openssl/blob/master/crypto/x509/x509_cmp.c#L226

我们做错了什么? --谢谢,

最佳答案

我知道这是一个旧线程。但它可以帮助其他人。要找出来并不容易。但我想我找到了一种方法,它适用于我测试过的证书。您需要 bouncycaSTLe 的 nuget 包,然后是这段代码。

 public async Task ExecuteAsync()
    {
        var issuer = GetIssuer(await GetServerCertificateAsync());
        System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance);


        var certString = Convert.ToBase64String(issuer.RawData);

        //Alles canonical maken (lowercase certificaat opvragen via bouncyCastle)
        //subject name omzetten naar Lowercase zoals OpenSSL doet.
        //een ASN1Object van maken alle bytes samen nemen en hash berekenen. WHOOPIEeee!!
        Org.BouncyCastle.X509.X509CertificateParser certParser = new Org.BouncyCastle.X509.X509CertificateParser();
        var cert = certParser.ReadCertificate(issuer.RawData);
        var subjectDNCanonical = new Org.BouncyCastle.Asn1.X509.X509Name(cert.SubjectDN.ToString().ToLower());
        var asn1Object = (Asn1Sequence)subjectDNCanonical.ToAsn1Object();
        List<byte[]> terms = new List<byte[]>();
        int finalLen = 0;
        foreach (var asn1Obj in asn1Object.ToArray())
        {
            byte[] term = asn1Obj.GetEncoded();
            term[9] = 0x0c; // change tag from 0x13 (printable string) to 0x0c
            terms.Add(term);
            finalLen += term.Length;
        }
        byte[] finalEncForw = new byte[finalLen];
        int j = 0;
        foreach (byte[] term in terms)
        {
            foreach (byte b in term)
            {
                finalEncForw[j++] = b;
            }
        }
        HashAlgorithm hash;
        hash = System.Security.Cryptography.SHA1.Create();
        var hashBytes = hash.ComputeHash(finalEncForw);
        ulong ret = (((ulong)hashBytes[0]) | ((ulong)hashBytes[1] << 8) | ((ulong)hashBytes[2] << 16) | ((ulong)hashBytes[3] << 24)) & 0xffffffff;
        Result = ret.ToString("X2").PadLeft(8, '0').ToLower();
    }

主要是 .ToLower 是 killer 。您不能使用 .NET 的默认 X509Certificate2 执行此操作。如果你这样做,它只会给 X509Name 一个主题的一部分。因此,这就是您必须将其转换为 BouncyCaSTLe 证书的原因。

关于c# - 在 C# 中生成 OpenSSL subject_name 哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36756166/

相关文章:

c# - 如何在 Selenium 中设置 Edge 的下载文件夹?

c# - 是否可以在.NET Core Web应用程序的任务管理器中设置显示名称?

c# - Chrome 风格的 C# 应用程序?

c# - GridView 中的按钮 : How do I know which Item?

ssl - 更改证书 csr 的指纹 SHA

python - Python 的 Crypto/X509 证书解析库

Ruby - 将两个散列与一些类似的键合并

algorithm - 列表哈希函数

perl - 是否可以在 perl 中使用散列(不是 hashrefs)的散列?

apache - Delphi 7/Indy 9 应用程序未通过 SSL 连接到 Apache