Мне нужно сгенерировать сертификаты, которые будут использоваться для безопасной связи между агентами. Каждый агент генерирует сертификат и должен отправить его в ЦС системы на другом компьютере, чтобы он был подписан (и доверен другим агентам). Я делаю это, используя C# со следующим кодом для агента:
//generate certificate
ECDsa elipticCurveNistP256Key = ECDsa.Create(ECCurve.CreateFromValue("1.2.840.10045.3.1.7")); // nistP256 curve
CertificateRequest certificateRequest = new CertificateRequest("CN=" + agentId, elipticCurveNistP256Key, HashAlgorithmName.SHA256);
certificateRequest.CertificateExtensions.Add(
new X509BasicConstraintsExtension(false, false, 0, false));
certificateRequest.CertificateExtensions.Add(
new X509KeyUsageExtension(
X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation,
false));
// Add the SubjectAlternativeName extension
var sanBuilder = new SubjectAlternativeNameBuilder();
sanBuilder.AddIpAddress(IPAddress.Parse(agentIpAddress));
certificateRequest.CertificateExtensions.Add(sanBuilder.Build());
certificateRequest.CertificateExtensions.Add(
new X509EnhancedKeyUsageExtension(
new OidCollection
{
new Oid("1.3.6.1.5.5.7.3.8")
},
true));
certificateRequest.CertificateExtensions.Add(
new X509SubjectKeyIdentifierExtension(certificateRequest.PublicKey, false));
И следующий код для системы CA:
X509Certificate2 signedCertificate = certificateRequest.Create(
caCertificatePFX,
DateTimeOffset.UtcNow.AddDays(-1),
DateTimeOffset.UtcNow.AddDays(30),
new byte[] {1, 2, 3, 4});
Конечно, я использую также код для связи между машинами, которые я здесь не показываю. Но у меня есть по крайней мере две проблемы:
Я хотел бы иметь полное разделение между генерацией сертификата и подписью, но даже при большом количестве попыток это был единственный код, который мне удалось получить работать. Если я не ошибаюсь, этот код имеет создание сертификата в системе CA, что не является идеальным сценарием (CA имеет доступ к секретному ключу агента), но если я не нашел лучшего, это то, что я могу принять.
Вторая проблема заключается в том, что даже если я приму первую проблему, мне все равно нужно будет отправить объект CertificateRequest с одного компьютера на другой, а CertificateRequest не будет сериализуемым. Я нашел метод CreateSigningRequest (), который «создает значение CertificationRequest PKCS # 10 в ASN.1 DER, закодированное в формате ASN.1, представляющее состояние текущего объекта». однако я не нашел способа сделать его объектом CertificateRequest, чтобы я мог запустить системный код CA.
Кто-нибудь знает, как я могу это сделать? Надеюсь полностью разделить генерацию сертификата и подпись сертификата, но если это невозможно, по крайней мере создать объект CertificateRequest обратно.
Я работаю. Net Framework 4.7.2, который мне нужно поддерживать для использования Ранее разработанные Windows Формы.
Спасибо