c# .net cryptography system.security

c# - Genere y firme solicitud de certificado utilizando.NET Framework puro



cryptography system.security (1)

Estoy tratando de usar código .net puro para crear una solicitud de certificado y crear un certificado a partir de la solicitud de certificado contra un certificado de CA existente que tengo disponible (ya sea en el almacén de certificados de Windows o como un archivo separado).

Sé que tengo las clases X509Certificate y X509Certificate2 disponibles para cargar certificados y obtener acceso a su información, pero no veo ninguna clase o funcionalidad dentro del espacio de nombres System.Security.Cryptography que pueda usarse para crear una solicitud de certificado o para firmar dicha solicitud de certificado para crear un nuevo certificado firmado.

Y eso, aunque la documentación en el espacio de nombres System.Security.Cryptography.Pkcs dice:

El espacio de nombres System.Security.Cryptography.Pkcs proporciona elementos de programación para los Estándares de criptografía de clave pública (PKCS), incluidos los métodos para firmar datos, intercambiar claves, solicitar certificados , cifrado y descifrado de clave pública y otras funciones de seguridad.

Entonces, ¿cómo puedo crear una solicitud de certificado y firmar esa solicitud para crear un nuevo certificado X509 usando solo clases .net puras de System.Security.Cryptography ?

Nota:

  • No quiero usar un ejecutable externo como openssl o MakeCert
  • No quiero usar BouncyCastle
  • No quiero usar la API de inscripción de certificados de Windows
  • No quiero usar las funciones nativas de la API Win32

Respuesta corta: puede comenzar en .NET Framework 4.7.2.

Esta funcionalidad se agregó originalmente a .NET Core 2.0 en la forma de la clase CertificateRequest , que puede generar una solicitud de firma de certificación PKCS # 10 o un certificado de clave pública X.509 (autofirmado o encadenado).

Las clases para esa característica se pusieron a disposición en .NET Framework 4.7.2.

using (RSA parent = RSA.Create(4096)) using (RSA rsa = RSA.Create(2048)) { CertificateRequest parentReq = new CertificateRequest( "CN=Experimental Issuing Authority", parent, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); parentReq.CertificateExtensions.Add( new X509BasicConstraintsExtension(true, false, 0, true)); parentReq.CertificateExtensions.Add( new X509SubjectKeyIdentifierExtension(parentReq.PublicKey, false)); using (X509Certificate2 parentCert = parentReq.CreateSelfSigned( DateTimeOffset.UtcNow.AddDays(-45), DateTimeOffset.UtcNow.AddDays(365))) { CertificateRequest req = new CertificateRequest( "CN=Valid-Looking Timestamp Authority", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); req.CertificateExtensions.Add( new X509BasicConstraintsExtension(false, false, 0, false)); req.CertificateExtensions.Add( new X509KeyUsageExtension( X509KeyUsageFlags.DigitalSignature | X509KeyUsageFlags.NonRepudiation, false)); req.CertificateExtensions.Add( new X509EnhancedKeyUsageExtension( new OidCollection { new Oid("1.3.6.1.5.5.7.3.8") }, true)); req.CertificateExtensions.Add( new X509SubjectKeyIdentifierExtension(req.PublicKey, false)); using (X509Certificate2 cert = req.Create( parentCert, DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(90), new byte[] { 1, 2, 3, 4 })) { // Do something with these certs, like export them to PFX, // or add them to an X509Store, or whatever. } } }

Respuesta más larga si está atascado en versiones anteriores: para lograr su objetivo sin agregar nuevas P / Invocaciones, deberá leer y comprender los siguientes documentos:

  • UIT-T X.680-201508, el lenguaje ASN.1
  • IETF RFC 5280 o ITU-T X.509 , los documentos que explican los campos en los certificados X.509.
  • IETF RFC 2986 , explica la solicitud de firma de certificación PKCS # 10
  • ITU-T X.690 , explica la familia de codificación BER para ASN.1 (incluido DER) que le indica cómo leer y escribir bytes para lograr el significado semántico de X.509 / PKCS # 10.

Y luego podría escribir un escritor / lector DER, y simplemente emitir los bytes para lo que desea.