[英]C# X509Certificate2 change issuer name
There is same question 7 years ago but solved using external library. 7 年前有同样的问题,但使用外部库解决了。 Now it is possible to change X509Certificate2
Issuer Name
without external library?现在可以在没有外部库的情况下更改 X509Certificate2
Issuer Name
吗?
fyi, I'm using .NET Framework 4.7.2仅供参考,我正在使用 .NET 框架 4.7.2
public static X509Certificate2 Create(string host)
{
var ecdsa = ECDsa.Create();
var request = new CertificateRequest($"CN={host}", ecdsa, HashAlgorithmName.SHA256);
var validFrom = DateTimeOffset.UtcNow;
var validUntil = DateTimeOffset.UtcNow.AddYears(5);
var certificate = request.CreateSelfSigned(validFrom, validUntil);
var certificateBytes = certificate.Export(X509ContentType.Pfx);
// ??? set issuer ???
return new X509Certificate2(certificateBytes);
}
For a self-signed certificate changing the issuer name would just make for a non-verifiable certificate (unless you share a private key with the issuer, which is a bad idea).对于自签名证书,更改颁发者名称只会生成不可验证的证书(除非您与颁发者共享私钥,这是一个坏主意)。
For a chain-signed certificate you can use one of the CertificateRequest.Create methods to either provide the issuer certificate (its subject name will be the new certificate's issuer name) or you can supply the issuer name and a signature generator (eg X509SignatureGenerator.CreateForECDsa(key)
) for full control (including making the aforementioned non-verifiable certificate).对于链签名证书,您可以使用其中一种CertificateRequest.Create方法来提供颁发者证书(其主题名称将是新证书的颁发者名称),或者您可以提供颁发者名称和签名生成器(例如
X509SignatureGenerator.CreateForECDsa(key)
) 用于完全控制(包括制作上述不可验证的证书)。
@bartojs answer is correct I have to use CertificateRequest.Create
. @bartojs 答案是正确的,我必须使用
CertificateRequest.Create
。
I'm creating self signing certificate for my MITM Proxy Server application, so here working code for generating certificate in.Net Framework 4.7.2 without external.dll library like Bouncy Castle or CERTENROLLIB我正在为我的 MITM 代理服务器应用程序创建自签名证书,所以这里是在没有 external.dll 库(如 Bouncy Castle 或 CERTENROLLIB)的情况下在.Net Framework 4.7.2 中生成证书的工作代码
public static X509Certificate2 CreateMyCertificate(string host, bool isCA)
{
var validFrom = DateTimeOffset.UtcNow;
var validUntil = DateTimeOffset.UtcNow.AddYears(8);
X509Certificate2 certificate;
RSA rsaKey = Program.rootRSA;
if (isCA)
{
// create exportable Root private key
// will be used later as global variable Program.rootRSA
CspParameters cspParams = new CspParameters
{
KeyContainerName = Guid.NewGuid().ToString()
};
rsaKey = new RSACryptoServiceProvider(2048, cspParams);
}
// Request a certificate with the common name as the host using the key pair.
// Common Name (AKA CN) represents the server name protected by the SSL certificate.
var request = new CertificateRequest(
$"CN={host}",
rsaKey,
HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1
);
// Add Certificate Extensions
request.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.1")
}, true)
);
if (isCA)
{
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, true, 1, false));
request.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(request.PublicKey, false));
request.CertificateExtensions.Add(
new X509KeyUsageExtension(X509KeyUsageFlags.CrlSign | X509KeyUsageFlags.KeyCertSign, false));
certificate = request.CreateSelfSigned(validFrom, validUntil);
}
else
{
SubjectAlternativeNameBuilder sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddDnsName(host.Replace("*.", ""));
request.CertificateExtensions.Add(sanBuilder.Build());
request.CertificateExtensions.Add(new X509Extension("2.5.29.35", Program.authorityKeyIdentifer, false));
request.CertificateExtensions.Add(new X509KeyUsageExtension(
X509KeyUsageFlags.KeyEncipherment, false));
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var unixTime = Convert.ToInt64((DateTime.UtcNow - epoch).TotalSeconds);
var serial = BitConverter.GetBytes(unixTime);
certificate = request.Create(Program.rootCert, validFrom, validUntil.AddDays(-5), serial);
certificate.PrivateKey = Program.rootCert.PrivateKey;
}
var certificateBytes = certificate.Export(X509ContentType.Pfx, "");
// return certificate with persisted private key
return new X509Certificate2(certificateBytes, "", X509KeyStorageFlags.Exportable);
}
Then use it like:然后像这样使用它:
rootCert
and rootRSA
rootCert
和rootRSA
rootCert = CreateMyCertificate("__MY_ROOT_CERTIFICATE", true);
rootCert
to trusted Root locationrootCert
导出/存储到受信任的根位置connect
request we can generate the cert usingconnect
请求,我们可以使用生成证书CreateMyCertificate("stackoverflow.com", false);
host
certificate make sure rootCert
is defined, because it will be used in CreateMyCertificate()
method, line belowhost
证书时,请确保定义了rootCert
,因为它将在CreateMyCertificate()
方法中使用,如下行if (isCA){...}
else
{
certificate = request.Create(Program.rootCert, validFrom, validUntil.AddDays(-5), serial);
}
note why you shoud not CERTENROLLIB:注意为什么你不应该 CERTENROLLIB:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.