Comment créer un certificat auto-signé en utilisant C#?

je dois créer un certificat auto-signé (pour le cryptage local - il n'est pas utilisé pour sécuriser les communications), en utilisant C#.

j'ai vu certaines implémentations utiliser P/Invoke Crypt32.dll, mais ils sont compliqués et il est difficile de mettre à jour les paramètres - et je voudrais aussi éviter P/invoquer si possible.

Je n'ai pas besoin de quelque chose qui est cross plate - forme-courir seulement sur Windows est assez bon pour je.

idéalement, le résultat serait un objet X509Certificate2 que je peux utiliser pour insérer dans le Windows certificate store ou Exporter vers un fichier PFX.

42
demandé sur rstackhouse 2012-12-10 21:46:24

5 réponses

cette implémentation utilise le CX509CertificateRequestCertificate objet COM (et amis - MSDN doc)certenroll.dll pour créer une demande de certificat auto signée et la signer.

l'exemple ci-dessous est assez simple (si vous ignorez les bits de com stuff qui se passe ici) et il y a quelques parties du code qui sont vraiment optionnelles (comme EKU) qui sont tout de même utiles et faciles à adapter à votre utilisation.

public static X509Certificate2 CreateSelfSignedCertificate(string subjectName)
{
    // create DN for subject and issuer
    var dn = new CX500DistinguishedName();
    dn.Encode("CN=" + subjectName, X500NameFlags.XCN_CERT_NAME_STR_NONE);

    // create a new private key for the certificate
    CX509PrivateKey privateKey = new CX509PrivateKey();
    privateKey.ProviderName = "Microsoft Base Cryptographic Provider v1.0";
    privateKey.MachineContext = true;
    privateKey.Length = 2048;
    privateKey.KeySpec = X509KeySpec.XCN_AT_SIGNATURE; // use is not limited
    privateKey.ExportPolicy = X509PrivateKeyExportFlags.XCN_NCRYPT_ALLOW_PLAINTEXT_EXPORT_FLAG;
    privateKey.Create();

    // Use the stronger SHA512 hashing algorithm
    var hashobj = new CObjectId();
    hashobj.InitializeFromAlgorithmName(ObjectIdGroupId.XCN_CRYPT_HASH_ALG_OID_GROUP_ID,
        ObjectIdPublicKeyFlags.XCN_CRYPT_OID_INFO_PUBKEY_ANY, 
        AlgorithmFlags.AlgorithmFlagsNone, "SHA512");

    // add extended key usage if you want - look at MSDN for a list of possible OIDs
    var oid = new CObjectId();
    oid.InitializeFromValue("1.3.6.1.5.5.7.3.1"); // SSL server
    var oidlist = new CObjectIds();
    oidlist.Add(oid);
    var eku = new CX509ExtensionEnhancedKeyUsage();
    eku.InitializeEncode(oidlist); 

    // Create the self signing request
    var cert = new CX509CertificateRequestCertificate();
    cert.InitializeFromPrivateKey(X509CertificateEnrollmentContext.ContextMachine, privateKey, "");
    cert.Subject = dn;
    cert.Issuer = dn; // the issuer and the subject are the same
    cert.NotBefore = DateTime.Now;
    // this cert expires immediately. Change to whatever makes sense for you
    cert.NotAfter = DateTime.Now; 
    cert.X509Extensions.Add((CX509Extension)eku); // add the EKU
    cert.HashAlgorithm = hashobj; // Specify the hashing algorithm
    cert.Encode(); // encode the certificate

    // Do the final enrollment process
    var enroll = new CX509Enrollment();
    enroll.InitializeFromRequest(cert); // load the certificate
    enroll.CertificateFriendlyName = subjectName; // Optional: add a friendly name
    string csr = enroll.CreateRequest(); // Output the request in base64
    // and install it back as the response
    enroll.InstallResponse(InstallResponseRestrictionFlags.AllowUntrustedCertificate,
        csr, EncodingType.XCN_CRYPT_STRING_BASE64, ""); // no password
    // output a base64 encoded PKCS#12 so we can import it back to the .Net security classes
    var base64encoded = enroll.CreatePFX("", // no password, this is for internal consumption
        PFXExportOptions.PFXExportChainWithRoot);

    // instantiate the target class with the PKCS#12 data (and the empty password)
    return new System.Security.Cryptography.X509Certificates.X509Certificate2(
        System.Convert.FromBase64String(base64encoded), "", 
        // mark the private key as exportable (this is usually what you want to do)
        System.Security.Cryptography.X509Certificates.X509KeyStorageFlags.Exportable
    );
}

Le résultat peut être ajouté à un certificat stocker en utilisant X509Store ou exporté en utilisant le X509Certificate2 méthodes.

pour une gestion complète et non liée à la plate-forme de Microsoft, et si vous êtes D'accord avec la licence de Mono, alors vous pouvez regarder X509CertificateBuilder Mono.Sécurité. Mono.La sécurité est autonome à partir de Mono, en ce sens qu'elle n'a pas besoin du reste de Mono pour fonctionner et peut être utilisée dans n'importe quel environnement .net compatible (par exemple l'implémentation de Microsoft).

61
répondu Guss 2016-11-23 20:37:34

une Autre option est d'utiliser le CLR de la Sécurité de la bibliothèque d'extensions à partir de CodePlex, qui met en œuvre une fonction d'aide à générer des auto-signé les certificats x509:

X509Certificate2 cert = CngKey.CreateSelfSignedCertificate(subjectName);

vous pouvez aussi regarder la mise en oeuvre de cette fonction (en CngKeyExtensionMethods.cs) pour voir comment créer l'auto-signé cert explicitement dans le code managé.

17
répondu dthorpe 2012-12-12 17:58:47

Vous pouvez utiliser le gratuit PluralSight.Crypto library pour simplifier programmatique de la création de l'auto-signé les certificats x509:

    using (CryptContext ctx = new CryptContext())
    {
        ctx.Open();

        X509Certificate2 cert = ctx.CreateSelfSignedCertificate(
            new SelfSignedCertProperties
            {
                IsPrivateKeyExportable = true,
                KeyBitLength = 4096,
                Name = new X500DistinguishedName("cn=localhost"),
                ValidFrom = DateTime.Today.AddDays(-1),
                ValidTo = DateTime.Today.AddYears(1),
            });

        X509Certificate2UI.DisplayCertificate(cert);
    }

PluralSight.Crypto nécessite .NET 3.5 ou plus tard.

9
répondu dthorpe 2014-09-23 18:31:07

depuis .NET 4.7.2 vous pouvez créer des certs auto-signés en utilisant Système.Sécurité.Cryptographie.X509certificats.CertificateRequest.

Par exemple:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

public class CertificateUtil
{
    static void MakeCert()
    {
        var ecdsa = ECDsa.Create(); // generate asymmetric key pair
        var req = new CertificateRequest("cn=foobar", ecdsa, HashAlgorithmName.SHA256);
        var cert = req.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));

        // Create PFX (PKCS #12) with private key
        File.WriteAllBytes("c:\temp\mycert.pfx", cert.Export(X509ContentType.Pfx));

        // Create Base 64 encoded CER (public key only)
        File.WriteAllText("c:\temp\mycert.cer",
            "-----BEGIN CERTIFICATE-----\r\n"
            + Convert.ToBase64String(cert.Export(X509ContentType.Cert), Base64FormattingOptions.InsertLineBreaks)
            + "\r\n-----END CERTIFICATE-----");
    }
}
1
répondu Duncan Smart 2018-09-27 10:44:29

C'est la version Powershell sur la façon de créer un certificat. Vous pouvez l'utiliser en exécutant la commande. Vérifier https://technet.microsoft.com/itpro/powershell/windows/pkiclient/new-selfsignedcertificate

modifier: vous avez oublié de dire qu'après avoir créé le certificat, vous pouvez utiliser le programme Windows "Gérer les certificats informatiques", pour exporter le certificat .CER ou autre type.

0
répondu Roger Deep 2017-05-27 15:25:42