使用私钥将 X509 证书导入 certlm (.NET Core 6)
Import X509 certificate to certlm with private key (.NET Core 6)
我正在生成 X509 证书以使用以下代码在 Azure 中使用 .NET 授权应用程序:
private static X509Certificate2 BuildSelfSignedCertificate(string CertificateName, int DaysValid)
{
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddDnsName("localhost");
sanBuilder.AddDnsName(Environment.MachineName);
X500DistinguishedName distinguishedName = new X500DistinguishedName($"CN={CertificateName}");
using RSA rsa = RSA.Create(2048);
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(sanBuilder.Build());
var certificate = request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(DaysValid)));
#pragma warning disable CA1416 // Validate platform compatibility
certificate.FriendlyName = CertificateName;
#pragma warning restore CA1416 // Validate platform compatibility
return certificate;
}
效果很好,但是当我使用以下方法导入证书时,不包括私钥:
X509Store store = new(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
但是,如果我将证书导出到一个字节数组并从该数组创建一个新的 X509Certificate2
对象,则可以正确导入私钥。
var cert = new X509Certificate2(certificate.Export(X509ContentType.Pkcs12, "password"), "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
请注意“您有一个与此证书对应的私钥”消息。
如何在不诉诸这种笨拙的解决方法的情况下导入证书 + 私钥?
How can I import the cert + private key without resorting to this awkward workaround?
首先将密钥创建为永久密钥。
using RSA rsa = RSA.Create(2048);
此行创建一个临时(仅 in-memory)私钥。相反你可以做
CngKeyCreationParameters keyParams = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = CngKeyCreationOptions.MachineKey,
Parameters =
{
new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.Persist),
},
};
using CngKey cngKey = CngKey.Create(CngAlgorithm.Rsa, Guid.NewGuid().ToString("D"), keyParams);
using RSA rsa = new RSACng(cngKey);
现在创建的证书与 already-persisted 密钥相关联。
(请注意,此代码段使用 MachineKey 且可导出,因为这就是 PFX 导入标志的问题)
我正在生成 X509 证书以使用以下代码在 Azure 中使用 .NET 授权应用程序:
private static X509Certificate2 BuildSelfSignedCertificate(string CertificateName, int DaysValid)
{
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(IPAddress.Loopback);
sanBuilder.AddIpAddress(IPAddress.IPv6Loopback);
sanBuilder.AddDnsName("localhost");
sanBuilder.AddDnsName(Environment.MachineName);
X500DistinguishedName distinguishedName = new X500DistinguishedName($"CN={CertificateName}");
using RSA rsa = RSA.Create(2048);
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.DataEncipherment | X509KeyUsageFlags.KeyEncipherment | X509KeyUsageFlags.DigitalSignature, false));
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection { new Oid("1.3.6.1.5.5.7.3.1") }, false));
request.CertificateExtensions.Add(sanBuilder.Build());
var certificate = request.CreateSelfSigned(new DateTimeOffset(DateTime.UtcNow.AddDays(-1)), new DateTimeOffset(DateTime.UtcNow.AddDays(DaysValid)));
#pragma warning disable CA1416 // Validate platform compatibility
certificate.FriendlyName = CertificateName;
#pragma warning restore CA1416 // Validate platform compatibility
return certificate;
}
效果很好,但是当我使用以下方法导入证书时,不包括私钥:
X509Store store = new(StoreName.My, StoreLocation.LocalMachine);
store.Open(OpenFlags.ReadWrite);
store.Add(cert);
store.Close();
但是,如果我将证书导出到一个字节数组并从该数组创建一个新的 X509Certificate2
对象,则可以正确导入私钥。
var cert = new X509Certificate2(certificate.Export(X509ContentType.Pkcs12, "password"), "password", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.Exportable);
请注意“您有一个与此证书对应的私钥”消息。
如何在不诉诸这种笨拙的解决方法的情况下导入证书 + 私钥?
How can I import the cert + private key without resorting to this awkward workaround?
首先将密钥创建为永久密钥。
using RSA rsa = RSA.Create(2048);
此行创建一个临时(仅 in-memory)私钥。相反你可以做
CngKeyCreationParameters keyParams = new CngKeyCreationParameters
{
ExportPolicy = CngExportPolicies.AllowPlaintextExport,
KeyCreationOptions = CngKeyCreationOptions.MachineKey,
Parameters =
{
new CngProperty("Length", BitConverter.GetBytes(2048), CngPropertyOptions.Persist),
},
};
using CngKey cngKey = CngKey.Create(CngAlgorithm.Rsa, Guid.NewGuid().ToString("D"), keyParams);
using RSA rsa = new RSACng(cngKey);
现在创建的证书与 already-persisted 密钥相关联。
(请注意,此代码段使用 MachineKey 且可导出,因为这就是 PFX 导入标志的问题)