如何将 CSR 文本文件转换为 .NET Core/Standard CertificateRequest 以进行签名?
Posted
技术标签:
【中文标题】如何将 CSR 文本文件转换为 .NET Core/Standard CertificateRequest 以进行签名?【英文标题】:How to convert a CSR text file into .NET Core/ Standard CertificateRequest for Signing? 【发布时间】:2021-05-02 18:04:05 【问题描述】:很多类似的问题,但我没有看到一个好的答案。
我有一个基于云的应用程序,并在现场的客户站点上安装了一个代理。我想让代理在安装后生成一个 CSR 并通过 HTTPS 将请求上传到云服务,在那里我将使用云服务证书(代理将信任)对其进行签名并返回签名证书。此证书将用于代理身份验证、加密和文件签名。
我可以很容易地完成 CSR:
public string GenerateAgentCsr(Guid customerId)
var domain = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
var domainDistinguishedName = string.Join(",DC=", domain.Split("."));
var distinguishedName = $"DC=Environment.MachineName,DC=domainDistinguishedName,O=customerId";
var rsa = RSA.Create(1024);
var request = new CertificateRequest(distinguishedName, rsa, HashAlgorithmName.SHA256,
RSASignaturePadding.Pkcs1);
request.CertificateExtensions.Add(new X509BasicConstraintsExtension(false, false, 0, false));
request.CertificateExtensions.Add(new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.DataEncipherment |
X509KeyUsageFlags.NonRepudiation, false));
var armored = request.AsCsr();
return armored;
public static string AsCsr(this CertificateRequest request)
var encoded = request.CreateSigningRequest();
var payload = Convert.ToBase64String(encoded);
using var stream = new MemoryStream();
using (var writer = new StreamWriter(stream, Encoding.UTF8, 512, true))
writer.WriteLine("-----BEGIN CERTIFICATE REQUEST-----");
writer.WriteLine(payload.Slice());
writer.WriteLine("-----END CERTIFICATE REQUEST-----");
writer.Flush();
stream.Position = 0;
using (var reader = new StreamReader(stream))
return reader.ReadToEnd();
...所以我可以将其发送到云服务器,但随后我立即遇到了问题。我的计划是有一个这样的方法:
public X509Certificate2 SignCertificate(CertificateRequest csr)
var signedCert = csr.Create(GetCertificateAuthorityCertificate(), DateTimeOffset.Now, DateTimeOffset.Now.AddYears(10),
new byte[] 1, 2, 3, 4 );
return signedCert;
...但我实际上无法将 CSR 转换为 CertificateRequest
。没有Parse
机制或构造函数允许这样做。
所以...一旦我有了 CSR,如何正确解析并使用我的云服务证书对其进行签名,以便我可以将其发送回代理?
【问题讨论】:
【参考方案1】:类型可以帮助您填充 CertificateRequest 对象的唯一方法是使用 System.Formats.Asn1.AsnReader
读取数据。
签署证书请求是一项重大决定。请求是否仅使用授权使用的名称?它是否将自己推销给另一个颁发证书的机构?是否有任何扩展请求您不理解其含义?它是否自称是时间戳权威、代码签名证书或任何其他有限用途?
通过签署外部请求,您是在尝试成为“真正的”CA。你在做撤销吗?您正在记录发行吗?
.NET 有 SubjectAlternativeNameBuilder 来帮助构建 SAN 扩展,但没有很好的方法来读回它们……因为 SubjectAlternativeNames 比它们通常使用的要复杂得多。所以没有好办法来回答名字的问题。
如果您使用受控访问,则更有限的版本是以您自己的自定义格式(另请参阅@ 987654322@)。然后你知道你没有被要求做你不想做的事情。不幸的是,PublicKey.CreateFromSubjectPublicKeyInfo
是 .NET 6 中的新功能。幸运的是,它很简单:
private static PublicKey CreateFromSubjectPublicKeyInfo(ReadOnlyMemory<byte> data)
AsnReader reader = new AsnReader(data, AsnEncodingRules.DER);
AsnReader spki = reader.ReadSequence();
reader.ThrowIfNotEmpty();
AsnReader algorithmIdentifier = spki.ReadSequence();
string algOid = algorithmIdentifier.ReadObjectIdentifier();
ReadOnlyMemory<byte> algParameters = default;
if (algOid.HasData)
algParameters = algorithmIdentifier.ReadEncodedValue();
algorithmIdentifier.ThrowIfNotEmpty();
byte[] publicKey = spki.ReadBitString(out _);
spki.ThrowIfNotEmpty();
return new PublicKey(
new Oid(algOid, null),
algParameters.ToArray(),
publicKey);
【讨论】:
这个想法是管理吊销,是的......我可能最终只是用公钥进行自签名,这对于我想要完成的事情可能已经足够了。以上是关于如何将 CSR 文本文件转换为 .NET Core/Standard CertificateRequest 以进行签名?的主要内容,如果未能解决你的问题,请参考以下文章
如何将带有参数数组的字符串 xml 转换为 .NET Core 中的对象
ASP.NET Core —上传.json文件并转换为List
将 WCF 应用程序从 .Net 框架转换为 .Net Core 时如何移植 <system.serviceModel> 配置?