Есть ли способ создать самоподписанные сертификаты (X509 v3 с альтернативным именем субъекта) с моим собственным корневым сертификатом для замены MakeCert.exe

У меня возникают проблемы с тем, что makecert не может создать самозаверяющий сертификат SSL с альтернативным именем субъекта (SAN). Последние версии Google Chrome выдают ошибку безопасности при доступе к веб-сайту через HTTPS. Я прочитал несколько статей, чтобы попытаться понять контекст, и пришел к выводу, что makecert достаточно устарела и не сможет поддерживать генерацию сертификата X509 v3 с помощью SAN. Есть ли альтернативные средства для создания самозаверяющего корневого сертификата и промежуточных сертификатов на основе этого корневого ЦС с использованием чего-то еще, что может работать в Windows 7 и более поздних версиях?

Корневой сертификат создается следующим образом:

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

Промежуточный сертификат с указанным выше Root 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-SelfsignedCertificateEx или New-SelfSignedCertificate для точного сопоставления с указанным выше параметром и создания сертификата с данным корневым центром сертификации.

Я буду очень благодарен за любую помощь в правильном направлении, пожалуйста.

На данный момент существует старое приложение, которое используют наши клиенты, которое использует 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


person Lone Wolf    schedule 19.07.2017    source источник
comment
Вы можете сделать все это с openssl.exe. Не по теме.   -  person user207421    schedule 19.07.2017
comment
Все это можно сделать с помощью командлета PowerShell New-SelfSignedCertificate.   -  person Crypt32    schedule 19.07.2017
comment
Спасибо EJP и Crypt32 за ваше драгоценное время. Я читал сообщения об openssl, однако в этом контексте мне нужно заменить упакованный makecert.exe другим исполняемым файлом или так, чтобы я мог его распространять. В основном происходит следующее: Приложение —> использует ядро ​​fiddler для проверки HTTPS-запросов —> вызывается makecert.exe с помощью processinfo для запуска внешнего процесса и создания корневого сертификата и сертификатов конечного объекта. Я попробовал New-SelfSignedCertificate, однако не могу создать цепочку доверия на месте, и не все параметры работают в Windows 7 и 8, 8.1.   -  person Lone Wolf    schedule 24.07.2017


Ответы (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

person bartonjs    schedule 19.07.2017