2

我遇到了makecert无法生成带有主题备用名称 (SAN) 的自签名 SSL 证书的问题。当通过 HTTPS 访问网站时,最新版本的 Google Chrome 会出现安全错误。我已经阅读了几篇文章以尝试了解上下文,并得出结论,它makecert已经足够老了,无法支持使用 SAN 生成 X509 v3 证书。是否有另一种方法可以使用可以在 Windows 7 及更高版本中运行的其他东西生成基于该根 CA 的自签名根证书和中间证书?

根证书生成如下:

makecert.exe -pe -ss Root -sr LocalMachine -n "CN=DIGITALMARKETRESEARCHAPPS PTY LTD, O=DIGITALMARKETRESEARCHAPPS PTY LTD, OU=DIGITALMARKETRESEARCHAPPS PTY LTD" -eku 1.3.6.1.5.5.7.3.1 -r -cy authority -a sha256

具有上述根 CA 的中间证书创建如下:

makecert.exe -pe -ss my -n "CN=www.myawesomesite.com.au, O=DIGITALMARKETRESEARCHAPPS PTY LTD, OU=DIGITALMARKETRESEARCHAPPS PTY LTD" -sky exchange -in "DIGITALMARKETRESEARCHAPPS PTY LTD"

我似乎无法找到一种方法来使用New-SelfsignedCertificateExNew-SelfSignedCertificate精确映射到上面的参数并使用给定的根 CA 创建证书。

我将非常感谢您在正确方向上的任何帮助。

目前,我们的客户使用这个旧应用程序makecert.exe来动态生成 SSL 证书。不幸的是,这是很久以前完成的,现在很难回去告诉他们改变整个架构。特别是 Google Xhrome 一直在抱怨这些证书是由makecert以下文章解释的:

http://news.thewindowsclub.com/deprecation-coming-to-google-chrome-heres-how-it-could-affect-your-workflow-88723/

http://www.telerik.com/blogs/understanding-fiddler-certificate-generators

4

1 回答 1

1

即将发布的 .NET Core 2.0 在此处添加了新的类来提供帮助。虽然我知道“powershell 可以”或“有一个版本的 powershell 可以”与 .NET Core 一起工作,但我不知道如何,所以这个答案可能需要一个适配器。

给定signingCert一个 X509Certificate2 实例,它HasPrivateKey==true

private static X509Certificate2 CreateNewCertificate(
    X509Certificate2 signingCert,
    int newRsaKeySize,
    IEnumerable<string> sanDnsEntries)
{
    var sanBuilder = new SubjectAlternativeNameBuilder();
    string primaryDnsName = null;

    foreach (string dnsEntry in sanDnsEntries)
    {
        // Let's just use the first one as the subject.
        primaryDnsName = primaryDnsName ?? dnsEntry;

        sanBuilder.AddDnsName(dnsEntry);
    }

    // New .NET Core Create(int) method.  Or use
    // rsa = RSA.Create(), rsa.KeySize = newRsaKeySize,
    // or (on .NET Framework) new RSACng(newRsaKeySize)
    using (RSA rsa = RSA.Create(newRsaKeySize))
    {
        var certRequest = new CertificateRequest(
            $"CN={primaryDnsName}, O=Et OU=Cetera",
            rsa,
            HashAlgorithmName.SHA256,
            RSASignaturePadding.Pkcs1);

        // Explicitly not a CA.
        certRequest.CertificateExtensions.Add(
            new X509BasicConstraintsExtension(false, false, 0, false));

        certRequest.CertificateExtensions.Add(
            new X509KeyUsageExtension(
                X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.KeyEncipherment,
                true));

        // TLS Server EKU
        certRequest.CertificateExtensions.Add(
            new X509EnhancedKeyUsageExtension(
                new OidCollection
                {
                    new Oid("1.3.6.1.5.5.7.3.1"),
                },
                false));

        // Add the SubjectAlternativeName extension
        certRequest.CertificateExtensions.Add(sanBuilder.Build());

        // Serial number.
        // It needs to be unique per issuer.
        // CA/Browser forum rules say 64 or more bits must come from a CSPRNG.
        // RFC 3280 says not to use more than 20 bytes.
        // Let's use 16 (two C# `long`s)
        byte[] serialNumber = new byte[16];

        using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
        {
            rng.GetBytes(serialNumber);
        }

        // If you care about monotonicity (and believe your clock is monotonic enough):
        {
            long ticks = DateTime.UtcNow.Ticks;
            byte[] tickBytes = BitConverter.GetBytes(ticks);

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(tickBytes);
            }

            Buffer.BlockCopy(tickBytes, 0, serialNumber, 0, tickBytes.Length);
        }

        DateTimeOffset now = DateTimeOffset.UtcNow;

        return certRequest.Create(
            signingCert,
            now,
            now.AddDays(90),
            serialNumber);
    }
}

API 文档

于 2017-07-19T14:47:12.273 回答