Много подобных вопросов, но я не вижу хорошего ответа.
У меня есть облачное приложение с агентом, установленным на сайтах клиентов в полевых условиях. Я хочу, чтобы агент после установки генерировал 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, как мне правильно проанализировать и подписать его с помощью моего сертификата облачной службы, чтобы я мог отправить его обратно агенту?