Extensiones de certificado personalizadas
Las extensiones personalizadas se agregan y eliminan en la página de Configuración del sistema EJBCA en la pestaña Extensiones de certificado personalizadas .
Descripción general
Se puede agregar una extensión simple que solo contenga un valor estático mediante la clase BasicCertificateExtension , ya implementada. Se pueden crear extensiones personalizadas más avanzadas implementando la interfaz org.cesecore.certificates.certificate.certextensions.CustomCertificateExtension y haciendo que la implementación esté disponible en la ruta de clases mediante ServiceLoader de Java. Para más información, consulte BasicCertificateExtension.java. Al implementar la interfaz de marcador y configurar los campos de propiedad y los valores predeterminados, EJBCA puede generar automáticamente una tabla de propiedades para la extensión.
Configuración de extensiones de certificado personalizadas
Las extensiones de certificado se configuran en la pestaña Extensiones de certificado personalizadas ( IU de CA → Configuración del sistema → Extensiones de certificado personalizadas ). Solo los administradores con la regla de acceso '/system_functionality/edit_available_custom_certificate_extensions' pueden agregar y eliminar extensiones de certificado personalizadas.
Las siguientes propiedades están disponibles para cada extensión:
Propiedad | Descripción |
Identificador de origen | El identificador único de objeto (OID) de la extensión. Valor obligatorio. También puede definirse como un OID comodín . |
Nombre para mostrar | Nombre para mostrar de la extensión en la página Editar perfil de certificado. Valor obligatorio. |
Clase de extensión | Nombre completo de la clase que implementa CertificateExtension. Valor obligatorio. |
Crítico | Define si la extensión debe marcarse como crítica en el certificado. |
Requerido | Habilitado por defecto, lo que hace que la extensión sea obligatoria en la solicitud. Desactivar "Obligatorio" permite que una solicitud contenga opcionalmente la extensión definida. De no ser así, se ignorará. |
Propiedades | Las propiedades son inherentes a cada implementación de extensión. |
Al agregar una nueva extensión de certificado personalizado, se especifican el OID y el nombre para mostrar y se crea una nueva extensión con los siguientes valores predeterminados:
Ruta de clase : org.cesecore.certificates.certificate.certextensions.BasicCertificateExtension
Crítico : Falso
Propiedades : Lista vacía de propiedades
Haga clic en la extensión recién creada para editar estos valores.
Una vez agregadas las extensiones, es posible seleccionarlas para un perfil de certificado en la página Editar perfil de certificado .
Usando la bandera Requerido
Cuando se selecciona una extensión como obligatoria (predeterminada) y se establece la propiedad de extensión dynamic=true , se debe proporcionar un valor. Puede ser un valor predeterminado, especificado en las propiedades de la extensión, o un valor especificado como Datos de Extensión de Certificado Personalizados (véase más adelante). En ocasiones, es necesario especificar una extensión como opcional para que el emisor (normalmente una RA) pueda decidir si se debe incluir o no. Al establecer Required=false, se puede excluir una extensión con un valor dinámico al no proporcionarla en la solicitud.
Definición de extensión de certificado y ASN.1
La definición de una extensión de certificado se encuentra en el RFC 5280. Específicamente, la codificación ASN.1 de las extensiones se encuentra en la sección 4.1 del RFC 5280 .
La sección especifica que el valor de extensión (extnValue) es una cadena de octetos que encapsula la secuencia de extensión real.
Extension ::= SEQUENCE {extnID OBJECT IDENTIFIER,critical BOOLEAN DEFAULT FALSE,extnValue OCTET STRING-- contains the DER encoding of an ASN.1 value-- corresponding to the extension type identified-- by extnID}Esta encapsulación la gestiona EJBCA para el tipo de valor que introduzca. Por ejemplo, si añade un valor de extensión DEROCTETSTRING, como se especifica a continuación, el ASN.1 real será una cadena de octetos encapsulada en otra cadena de octetos. Asimismo, los datos con codificación hexadecimal que introduzca como DEROBJECT corresponden a la "codificación DER de un valor ASN.1 correspondiente al tipo de extensión", como se especifica en el bloque ASN.1 anterior.
OCSP debe graparse
Ejemplo de configuración de extensión para la extensión de función OCSP Must Staple TLS:
Identificador de objeto: 1.3.6.1.5.5.7.1.24
Etiqueta: OCSP debe graparse
Clase de extensión: Extensión de certificado básico
Crítico: falso
Obligatorio: falso
Propiedades:
Dinámica: falsa
Codificación: DEROBJECT
Valor: 3003020105
O para fines ilustrativos, también puede establecer lo siguiente:
Propiedades:
Dinámica: verdadera
Codificación: DEROBJECT
Valor: (vacío)
Al marcar los datos de extensión de certificado personalizado en el perfil de entidad final, aparecerá un campo de ingreso de Datos de extensión de certificado al agregar o editar entidades finales.
Si este campo se deja vacío (y no se ha especificado ningún valor estático para la extensión), la generación de un certificado para la entidad final dará como resultado que no se agregue ninguna extensión al certificado emitido.
Al ingresar los siguientes datos en el campo de ingreso de Datos de extensión del certificado, se agregará la extensión OCSP Must Staple al certificado emitido:
1.3 . 6.1 . 5.5 . 7.1 . 24 .value= 3003020105Contenido del certificado emitido (de dumpasn1 ...) :
OBJECT IDENTIFIER '1 3 6 1 5 5 7 1 24'OCTET STRING, encapsulates {SEQUENCE {INTEGER 5}} OID comodín
El OID de la extensión puede configurarse como un comodín, por ejemplo, *.1.2.3 . Esto hará que la configuración coincida con cualquier OID solicitado , coincidiendo con el patrón (terminando así en .1.2.3 ). Una vez encontrado el OID, el valor dinámico de la solicitud se utilizará en el certificado. Dado que el comodín en sí no es un OID válido, siempre debe haber un OID real que coincida con él en la solicitud (a menos que se borre la opción "Required" , en cuyo caso se ignora). Por lo tanto, las configuraciones de comodines no pueden recurrir al valor estático definido si la extensión no se encuentra en la solicitud.
Eliminar una extensión de certificado personalizada
Si se elimina una extensión de certificado personalizada, actualmente en uso en un perfil de certificado, de la lista de extensiones disponibles en Extensiones de Certificado Personalizadas , se mostrará una advertencia con los perfiles de certificado que la utilizan. La extensión no se eliminará del perfil de certificado, ya que aún se utiliza. Sin embargo, no se podrá utilizar ni formará parte de ningún certificado emitido después de la eliminación y se mostrará como OID (Ya no se utiliza. Desactive esta opción) en la página Editar Perfil de Certificado . Para eliminar una extensión en uso del perfil de certificado, bórrela manualmente de la lista de Extensiones de Certificado Personalizadas Usadas en la página Editar Perfil de Certificado .
Extensión del certificado básico
Para crear una extensión de certificado básica, configure la ruta de clase en 'org.cesecore.certificates.certificate.certextensions.BasicCertificateExtension' (configuración predeterminada) y especifique la codificación y el valor de las propiedades ( el valor es opcional si hay una propiedad 'dynamic=true').
La siguiente tabla enumera las codificaciones disponibles y cómo se interpreta su valor.
Codificación | Valor |
DERBITSTRING | Una cadena que contiene los caracteres '0' y '1'. El valor introducido se codificará en una cadena de bits ASN.1 con el valor introducido. Por ejemplo, "10011011". |
DERINTEGER | Una cadena que contiene solo dígitos decimales. El valor que introduzca se codificará en un entero ASN.1 con el valor introducido. Por ejemplo, "123". |
DEROCTETSTRING | Una cadena que contiene una representación de datos hexadecimales. El valor que introduzca se codificará en una cadena de octetos ASN.1 con el valor introducido. Por ejemplo, "mi cadena". |
DERBOOLEAN | La cadena es 'true' o 'false'. El valor que introduzca se codificará en un booleano ASN.1. |
CADENA IMPRIMIBLE | Una cadena que contiene caracteres imprimibles válidos (az, 0-9). El valor que introduzca se codificará en una cadena imprimible ASN.1, con las limitaciones del conjunto de caracteres. |
DERUTF8STRING | Una cadena en formato UTF-8. El valor que introduzca se codificará en una cadena ASN.1 UTF-8, con menos limitaciones de caracteres que una cadena imprimible. |
DERIA5STRING | Una cadena IA5String ASN.1 que contiene caracteres de cadena imprimibles válidos (az, 0-9). |
DERNULL | Valor vacío. Se codifica en un valor ASN.1 NULL, que en realidad es una etiqueta y, por lo tanto, se codifica en bytes ASN.1. |
DESROBAR | El valor DER hexadecimal de las extensiones. Puede usarlo para crear una extensión con secuencias, etc. Los datos hexadecimales que introduzca corresponden a la "codificación DER de un valor ASN.1 correspondiente al tipo de extensión", como se especifica en la sección 4.1 de RFC5280 (véase más arriba). |
CRUDO | El valor de la matriz de bytes de las extensiones, codificado en hexadecimal. Puede proporcionar cualquier dato codificado en hexadecimal para usarlo como bytes del valor de la extensión, incluso datos que infrinjan la norma RFC5280. No lo utilice a menos que tenga una razón heredada que requiera crear certificados con codificación no válida. |
En 'src/java/certextensions.properties' se ofrecen ejemplos de extensiones de certificado que puede configurar con BasicCertificateExtension.
Políticas de aplicaciones de MS
Tipo de certificado de Netscape
Comentario de Netscape
URL de revocación de NetscapeCAR
URL de revocación de Netscape
...
Si la propiedad dinámica se configura como verdadera , el valor de la extensión puede obtenerse de los datos de extensión proporcionados con la entidad final. Para obtener más información sobre cómo agregar datos de extensión mediante la Web de administración, consulte Datos de extensión de certificado personalizados .
Creación de una extensión personalizada a partir de un certificado existente
<p >Si tiene un certificado existente con una extensión específica que desea agregar en EJBCA, y la extensión aún no está presente como una opción en la interfaz de usuario de EJBCA, puede extraer la extensión del certificado existente y agregarla como una extensión personalizada.Si tiene un certificado con restricciones de política, un volcado de OpenSSL puede verse así:
>openssl x509 -in cert.pem -text...X509v3 Policy Constraints:Require Explicit Policy:0, Inhibit Policy Mapping:0X509v3 Inhibit Any Policy:0...Para agregar esta extensión de restricciones de políticas a EJBCA, haga lo siguiente.
Extraiga los datos codificados DER reales:
>openssl asn1parse -in cert.pem -i...1555:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Policy Constraints1560:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:30068001008101001570:d=4 hl=2 l= 10 cons: SEQUENCE1572:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Inhibit Any Policy1577:d=5 hl=2 l= 3 prim: OCTET STRING [HEX DUMP]:020100...Luego, para agregar el valor 3006800100810100 como una extensión de certificado personalizado DEROBJECT:
Vaya a Configuración del sistema → Extensiones de certificado personalizadas y especifique lo siguiente:
OID = 2.5.29.36
Etiqueta =PolicyConstraints_Explicit0_Inhibit0 (cualquier etiqueta que considere apropiada y lógica para la configuración de su sistema).
Haga clic en Agregar .
Haga clic en Editar para la entrada recién creada y especifique lo siguiente:
Dinámico = falso
Codificación =DEROBJECT
Valor = 3006800100810100
Haga clic en Guardar .
A continuación, edite un perfil de certificado y seleccione "PolicyConstraints_Explicit0_Inhibit0 " en la lista " Extensiones de certificado personalizadas utilizadas" . Por último, emita el certificado y verifique que la extensión esté presente y sea la esperada.
Implementación de una extensión de certificado avanzada
Para crear una extensión avanzada, necesita crear una clase Java que implemente la interfaz CustomCertificateExtension. Recomendamos extender la clase StandardCertificateExtension. El método getValue es obligatorio y los datos de usuario actuales, la CA y el perfil del certificado se envían a la extensión para generar extensiones dinámicas.
Además de los valores estáticos definidos en Admin Web > Configuración del sistema > Extensiones de certificado personalizadas , también es posible obtener valores de los datos de extensión en el almacén de información extendida de la entidad final. Una buena opción es usar el oid de extensión como prefijo de la clave de la propiedad para asociar el valor con esta extensión.
A continuación se muestra un ejemplo de una extensión avanzada. Para añadir esta extensión a EJBCA, implemente la clase como parte del archivo ejbca.ear. Esta debería aparecer en la lista de Clases de Extensión al editar una extensión personalizada en Configuración del Sistema > Extensiones de Certificado Personalizadas . El archivo se encuentra automáticamente gracias a la implementación de la interfaz CustomCertificateExtension.
public class SomeAdvancedCertificateExtension extends StandardCertificateExtension implements CustomCertificateExtension {private static String PROPERTY_SOMEPROPERTY = "someproperty";public SomeAdvancedCertificateExtension() {super.setDisplayName("SomeAdvancedCertificateExtension");}@Overridepublic Map< String , String[]> getAvailableProperties() {Map< String , String[]> map = new HashMap<>();map.put(PROPERTY_SOMEPROPERTY, new String[]{"a", "b", "c"});return map;}/*** The main method that should return a byte[] with the ASN.1 encoded data to be putin the extension valud* using the input data (optional) or defined properties (optional)** @seeorg.cesecore.certificates.certificate.certextensions.CertificateExtension#getValueEncoded*/@Overridepublic byte[] getValueEncoded(EndEntityInformation userData, CA ca, CertificateProfilecertProfile, PublicKey userPublicKey,PublicKey caPublicKey, CertificateValidity val )throws CertificateExtentionConfigurationException, CertificateExtensionException {try {// Optionally get dynamic values for this extension//String dynamicValue = userData.getExtendedinformation().getExtensionData(getOID() + ".someotherproperty");String value = getProperties().getProperty("FOO");DERPrintableString asn1value = new DERPrintableString(value);return asn1value.toASN1Primitive().getEncoded();} catch (IOException e) {throw new CertificateExtensionException("Error constructing certificateextension SomeAdvancedCertificateExtension.", e);}}/*** @deprecated use getValueEncoded instead.*/public ASN1Encodable getValue(EndEntityInformation userData, CA ca, CertificateProfilecertProfile, PublicKey userPublicKey, PublicKey caPublicKey, CertificateValidity val)throws CertificateExtensionException, CertificateExtentionConfigurationException {throw new UnsupportedOperationException("Use getValueEncoded instead");}}