Как создать самосертифицированный сертификат x509, действительный на моем компьютере - PullRequest
0 голосов
/ 07 февраля 2019

Мне нужно создать самозаверяющий сертификат x509, который будет признан действительным на моем компьютере с помощью кода C #.

При необходимости его можно запустить с правами администратора.

Мой текущий кодэто следующее

public static X509Certificate2 GenerateCertificate(string name)
{
    string subjectName = $"CN={name}";
    using (RSA rsa = RSA.Create(2048))
    {
        CertificateRequest req = new CertificateRequest(
            subjectName,
            rsa,
            HashAlgorithmName.SHA256,
            RSASignaturePadding.Pkcs1);

        req.CertificateExtensions.Add(
            new X509BasicConstraintsExtension(false, false, 0, false));

        req.CertificateExtensions.Add(
            new X509KeyUsageExtension(
                X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
                false));

        req.CertificateExtensions.Add(
            new X509EnhancedKeyUsageExtension(
                new OidCollection
                {
                    new Oid("1.3.6.1.5.5.7.3.8")
                },
                true));

        req.CertificateExtensions.Add(
            new X509SubjectKeyIdentifierExtension(req.PublicKey, false));

        return req.CreateSelfSigned(
            DateTimeOffset.UtcNow.AddDays(-1),
            DateTimeOffset.UtcNow.AddYears(50));
    }
}

public static X509Certificate2 GetOrCreateCertificate(string serverName)
{
    using (X509Store store = new X509Store(StoreLocation.LocalMachine))
    {
        X509Certificate2 certificate;
        store.Open(OpenFlags.ReadWrite);
        X509Certificate2Collection certificateCollection = store.Certificates.Find(X509FindType.FindBySubjectName, serverName, true);//With true, my certificates are not returned
        if (certificateCollection.Count > 0)
        {
            certificate = certificateCollection[0];
            return certificate;
        }

        certificate = GenerateCertificate(serverName);
        store.Add(certificate);

        return certificate;
    }
}

В настоящее время, если я захожу в Windows MMC, оснастка сертификата, я вижу сертификат, но он считается недействительным.

Что я пропустил?

РЕДАКТИРОВАТЬ

1 Ответ

0 голосов
/ 08 февраля 2019

Похоже, проблема в том, что система не доверяет новому сертификату.

Чтобы доверять, корень цепочки сертификатов должен быть представлен в одном из следующихмагазины:

  • LocalMachine \ Root
  • LocalMachine \ ThirdPartyRoot
  • CurrentUser \ Root

(есть и другиезадействованные магазины, для корневых прав, управляемых доменом)

Итак, после того, как вы выполните

certificate = GenerateCertificate(serverName);
store.Add(certificate);

Вы также захотите сделать

using (X509Store rootStore = new X509Store(StoreName.Root, StoreLocation.LocalMachine))
using (X509Certificate2 withoutPrivateKey = new X509Certificate2(certificate.RawData))
{
    rootStore.Open(OpenFlags.ReadWrite);
    rootStore.Add(withoutPrivateKey);
}

Теперь системасможет проверить (одноузловую) цепочку до доверенного сертификата, а ограничение validOnly: true для Find будет считать сертификат действительным (что для этого метода означает доверенную цепочку и срок ее действия не истек).

...