如何使用C#创建自签名证书? [英] How to create a self-signed certificate using C#?

查看:256
本文介绍了如何使用C#创建自签名证书?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要使用C#创建自签名证书(用于本地加密 - 它不用于保护通信)。

I need to create a self-signed certificate (for local encryption - its not used to secure communications), using C#.

我看过一些使用 P / Invoke Crypt32。 dll ,但它们很复杂,很难更新参数 - 我也想避免P / Invoke如果可能的话。

I've seen some implementations that use P/Invoke with Crypt32.dll, but they are complicated and its hard to update the parameters - and I would also like to avoid P/Invoke if at all possible.

'

理想情况下,结果是一个X509Certificate2对象,我可以使用它来插入到


Ideally the result would be an X509Certificate2 object that I can use to insert into the Windows certificate store or export to a PFX file.

推荐答案

此实现使用 CX509CertificateRequestCertificate COM对象(和朋友 - MSDN文档)从 certenroll.dll 创建自签名证书请求并签名。

This implementation uses the CX509CertificateRequestCertificate COM object (and friends - MSDN doc) from certenroll.dll to create a self signed certificate request and sign it.

下面的例子是非常直接的(如果你忽略COM的东西,这里的位),并且有一些部分的代码是真正可选的

The example below is pretty straight forward (if you ignore the bits of COM stuff that goes on here) and there are a few parts of the code that are really optional (such as EKU) which are none-the-less useful and easy to adapt to your use.

public static X509Certificate2 CreateSelfSignedCertificate(string subjectName)
{
    // create DN for subject and issuer
    var dn = new X500DistinguishedName();
    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
    );
}

结果可以使用 X509Store 或使用 X509Certificate2 方法导出。

The result can be added to a certificate store using X509Store or exported using the X509Certificate2 methods.

到微软的平台,如果你确定Mono的许可,那么你可以看看 X509CertificateBuilder _Mono.Security> Mono.Security 。 Mono.Security是Mono独立的,因为它不需要运行Mono的其余部分,可以在任何兼容的.Net环境(例如Microsoft的实现)中使用。

For a fully managed and not tied to Microsoft's platform, and if you're OK with Mono's licensing, then you can look at X509CertificateBuilder from Mono.Security. Mono.Security is standalone from Mono, in that it doesn't need the rest of Mono to run and can be used in any compliant .Net environment (e.g. Microsoft's implementation).

这篇关于如何使用C#创建自签名证书?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆