我很想知道是否有一种简洁的方法来创建一个与下面的New-SelfSignedCertificate
命令相当的自签名证书(例如,其他提供商也可以)。我想只使用没有P / Invoke的.NET库或Bouncy Castle等外部库,或者不使用应用程序中的PowerShell。
New-SelfSignedCertificate -DnsName $certificateName -CertStoreLocation $certificateStore -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certificateNotAfter
我认为最简单的替代方法是调用PowerShell或使用Nuget库,如Bouncy Castle,如果没有外部设施这是不可行的?虽然感觉如果我知道如何构建证书,但是可以创建一个字节数组模板等,并在X509Certificate2
构造函数中使用它。
似乎需要
public X509Certificate2 GenerateCertificate(string fileName, string password, string subjectName, StoreName storeName, DateTime endDate, DateTime notAfter, string provider = "Microsoft Enhanced RSA and AES Cryptographic Provider")
{
//Could provider be taken from https://stackoverflow.com/questions/43474902/generate-self-signed-rsa-2048-sha-256-certificate-pfx-file-using-openssl?
var newCertificate = new X509Certificate2(fileName, password, X509KeyStorageFlags.Exportable);
/*
# The following creates a self-signed certificate with one year of running time.
$currentDate = Get-Date
$certificateEndDate = $currentDate.AddYears(1)
$certificateNotAfter = $certificateEndDate.AddYears(1)
$certificateName = "https://www.test.com/test"
$certificateStore = "Cert:\LocalMachine\My"
New-SelfSignedCertificate -DnsName $certificateName -CertStoreLocation $certificateStore -KeyExportPolicy Exportable -Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" -NotAfter $certificateNotAfter
*/
}
<编辑:很快就发现使用普通的.NET没有一个好的方法。
我发现了一些选项:
Steve Syfuhs 的博客文章Creating Authority-Signed and Self-Signed Certificates in .NET和使用Mono扩展程序Mono.Security won't set multiple KeyUsages的另一篇SO帖子。除了已经讨论过的选择之外,它还是“像这样的东西”。
答案 0 :(得分:10)
在任何已发布的.NET版本中都没有创建证书。
.NET Core 2.0 (尚未发布,但很快就会发布),.NET Framework 4.7.2已通过CertificateRequest添加了此功能。可以执行自签名证书,链式签名证书或PKCS#10证书/证书签名请求。)
PowerShell命令结合了三件事:
创造一些"几个装饰"自签名证书,适用于localhost上的TLS服务器身份验证:
X509Certificate2 certificate = null;
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName("localhost");
// 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=localhost",
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());
DateTimeOffset now = DateTimeOffset.UtcNow;
certificate = certRequest.CreateSelfSigned(now, now.AddDays(365.25));
}
这个创建的证书有一个短暂的私钥 - 它当前没有写入磁盘。如果您不关心它使用的密钥存储提供商,那么此时您最好的选择是将证书(和私钥)导出为PFX / PKCS#12,然后使用{{1}重新导入它(和PersistKeySet
,因为你想要),并将导入的副本添加到你选择的X509Store。
如果您关心密钥存储提供程序(在您的情况下是CAPI CSP),或者您希望避免导出/导入,则可以使用预先保留的密钥创建它。因此,您要将Exportable
替换为
CAPI:
RSA.Create(newRsaKeySize)
CNG:
var cspParameters = new CspParameters(
/* PROV_RSA_AES */ 24,
"Microsoft Enhanced RSA and AES Cryptographic Provider",
Guid.NewGuid().ToString());
using (RSA rsa = new RSACryptoServiceProvider(newRsaKeySize, cspParameters))
然后以通常的方式将其添加到打开的X509Store实例中。
感觉就像我知道如何构建证书一样,可以创建一个字节数组模板等,并在X509Certificate2构造函数中使用它。
真。但这有点棘手。您需要学习ASN.1(ITU-T X.680),DER(ITU-T X.690)和X.509(RFC 5280或ITU-T X.509)。如果您想创建与私钥配对的证书,那么您需要学习PFX / PKCS#12(RFC 7292,但仅限于某些较旧的选项,除非您仅限Win10这也有一堆必备知识。
我认为这些都是有趣的东西需要学习,并且要知道好的事情......但是当我开始在白板上涂鸦DER时,我的同事给了我奇怪的外观,所以我可能不代表普通开发人员" fun"。
的意见