Interfaz REST de EJBCA

A continuación se incluye información sobre la interfaz REST EJBCA para operaciones de gestión de certificados y administración de CA.

Descripción general de la API

La API REST de gestión de certificados EJBCA contiene puntos finales diseñados para la integración con EJBCA mediante la gestión de CA, la gestión de tokens criptográficos, la gestión de certificados y los servicios web RESTful ConfigDump. Esto facilita la integración y facilita la interacción HTTP para las partes más cruciales de EJBCA.

El alcance de la API es limitado en comparación con el conjunto completo de funciones que ofrece EJBCA y ofrece funciones como solicitudes de certificados, inscripción, revocación, importación y exportación de configuraciones de ConfigDump, entre otras. Para obtener una descripción completa de las funciones, consulte Recursos .

EJBCA Community incluye la API REST de inscripción para la inscripción de certificados, un subconjunto de la API REST de administración completa incluida en EJBCA Enterprise. Para ayudarle a comenzar e integrarse con EJBCA Community, ofrecemos un cliente REST de código abierto para EJBCA Community Edition. Consulte Easy Rest Client para EJBCA en GitHub .


Referencia de la API REST

Cada versión de EJBCA se incluye con una referencia de API REST generada automáticamente, disponible en la URL https://localhost:8442/ejbca/doc/rest/ si se implementa.

imágenes/descargar/archivos adjuntos/143749665/image2019-5-27_14-49-24.png

Interfaz de usuario Swagger

Swagger UI te permite visualizar e interactuar con los recursos de la API. El entorno de Swagger UI está disponible en tu navegador en la URL https://localhost:8443/ ejbca/swagger-ui (usa el puerto 8443, ya que la API REST utiliza autenticación con certificado de cliente).

imágenes/descargar/archivos adjuntos/143749665/image2019-5-27_14-50-18.png

La interfaz de usuario Swagger solo está disponible si crea EJBCA en modo de no producción, es decir, con ejbca.productionmode=false establecido en conf/ejbca.properties , y si REST está activado como protocolo (ver a continuación).

Empezando

La API REST de administración de certificados EJBCA está deshabilitada de forma predeterminada. Para habilitar el servicio, vaya a Administrador Web > Configuración del sistema > Configuración del protocolo y seleccione Habilitar para el punto final REST que desee usar.

imágenes/descargar/archivos adjuntos/143749665/rest_endpoints.png

La integración con la API REST y el consumo de la respuesta se pueden realizar con cualquier herramienta. Para solicitudes GET básicas, cualquier navegador web es suficiente; para una mejor integración, se recomienda una biblioteca REST o una herramienta similar.

A continuación se muestra un ejemplo de una solicitud básica:

GET https: //localhost:8443/ejbca/ejbca-rest-api/v1/certificate/status

El resultado es la siguiente respuesta JSON. Tenga en cuenta que la versión y la revisión pueden variar.

{
"status" : "OK" ,
"version" : "1.0" ,
"revision" : "ALPHA"
}

Puede acceder a la URL anterior mediante, por ejemplo, cURL, su navegador o cualquier otra herramienta. Tenga en cuenta que la API REST requiere autenticación mediante certificado de cliente (consulte Autenticación) .

Seguridad para puntos finales REST

Todos los endpoints REST se pueden invocar desde navegadores. Los endpoints REST EJBCA pueden invocarse maliciosamente desde equipos de administrador mediante clickjacking o métodos CSRF. En estos casos, el navegador también implementa medidas de autenticación por defecto. Los navegadores modernos garantizan la seguridad de las llamadas de origen cruzado llamando al método HTTP OPTION en el endpoint REST correspondiente antes de enviar la solicitud. Esta verificación previa falla en los endpoints REST EJBCA, ya que OPTION no está implementado. Desafortunadamente, esta comprobación solo se realiza si la llamada HTTP se realiza mediante JavaScript. Esto lo deja vulnerable al envío de formularios HTML para solicitudes GET/POST, que deberían estar protegidas desde el backend mediante validaciones adecuadas.

En EJBCA 7.11.0, esto se soluciona mediante la exigencia de un encabezado personalizado para las llamadas procedentes de un navegador. El nombre de este encabezado personalizado se puede modificar en la interfaz de administración > Configuración del sistema, en la pestaña Protocolo disponible . Está activo por defecto y también se puede desactivar desde allí. Las llamadas a servicios de backend y las llamadas a navegador se distinguen por la presencia de cualquiera de los dos encabezados prohibidos "Sec-Fetch-Mode" y "Sec-Fetch-Dest". Por lo tanto, no debería haber ningún impacto en los servicios de backend a menos que estos encabezados se reenvíen a EJBCA.

Además, la mayoría de los navegadores modernos, excepto Safari, inyectan estos encabezados prohibidos. Esta medida de protección no está disponible en el modo no productivo de EJBCA.

imágenes/descargar/archivos adjuntos/143749665/sec_header.png

Integración con la API REST

Las solicitudes a la API se envían mediante URL RESTful con los métodos HTTP estándar: GET, POST, PUT. Además, algunos endpoints aceptan un cuerpo de solicitud JSON. En conjunto, cada solicitud consta del método HTTP, la URL del endpoint y (en algunos casos) un cuerpo de solicitud. Algunos endpoints requieren la inclusión de un encabezado de método HTTP:

Content-Type: application/json

Generalmente, las respuestas constan de un encabezado HTTP que incluye un código de estado RFC 2616 y un cuerpo de respuesta en formato aplicación/json. Para obtener información sobre las excepciones, consulte Respuestas .

En caso de error, el cuerpo de la respuesta contiene un mensaje de error apropiado que describe el evento.

Recursos

La API REST de gestión de certificados proporciona las siguientes URL de recursos base:

/ejbca/ejbca-rest-api/v1/ca_management/
/ejbca/ejbca-rest-api/v1/ca/
/ejbca/ejbca-rest-api/v1/certificate/
/ejbca/ejbca-rest-api/v1/configdump/
/ejbca/ejbca-rest-api/v1/cryptotoken/
/ejbca/ejbca-rest-api/v1/endentity/
/ejbca/ejbca-rest-api/v2/certificate/

Cada recurso proporciona puntos finales de interacción:

  • Los puntos finales bajo el recurso /ca_management/ permiten manipular las CA, por ejemplo, activar y desactivar una CA. ENTERPRISE

  • El recurso /ca/ permite recuperar certificados de CA, CRL, etc. ENTERPRISE

  • El recurso /certificate/ maneja la inscripción de certificados, la revocación y otros flujos de trabajo relacionados con la administración de certificados.

  • El recurso /configdump/ gestiona la importación y exportación de configuraciones (editores, autoridades de certificación, roles, etc.) a través de la herramienta ConfigDump . ENTERPRISE

  • El recurso /cryptotoken/ gestiona la activación, desactivación y generación de claves de tokens criptográficos. ENTERPRISE

  • El recurso /endentity/ gestiona la gestión de entidades finales. ENTERPRISE

Para obtener un conjunto completo de todos los puntos finales, entradas requeridas, respuestas y otras descripciones de puntos finales, consulte la Referencia de API REST o pruébelo en la interfaz de usuario de Swagger .

Solicitudes

Cada URL de punto final se construye de la misma manera mediante la siguiente estructura:

https: //[DOMAIN_NAME]:[PORT]/ejbca/ejbca-rest-api/[API_VERSION]/[RESOURCE]/[IDENTIFIER]/[OPERATION]?[QUERY_PARAM]

Explicación

  • DOMAIN_NAME: Nombre de dominio de la instancia EJBCA, por ejemplo: localhost.

  • PUERTO: Puerto seguro de la instancia EJBCA, por ejemplo: 8443 .

  • API_VERSION: Versión de la API REST, por ejemplo: v1 .

  • RECURSO: Uno de los dos recursos base /ca/ o /certificate/ .

  • IDENTIFICADOR: Identificador de la entidad sobre la que se realizará la operación. Puede ser un DN de sujeto, un número de serie o ambos. Un identificador compuesto podría ser .../{issuer_dn}/{certificate_serial_number_hex}/revocationstatus .

  • OPERACIÓN: La operación a realizar, por ejemplo: /revocationstatus .

  • QUERY_PARAM: Parámetros de consulta HTTP. Algunos puntos finales aceptan parámetros de consulta en lugar de un cuerpo JSON. Por ejemplo , .../revoke?reason=KEY_COMPROMISE .

Tenga en cuenta que no todos los puntos finales requieren el identificador ni los parámetros de consulta. Por ejemplo, lo siguiente no es específico de una entidad y no acepta un identificador:

GET https: //localhost:8443/ejbca/ejbca-rest-api/v1/ca/status

Métodos

Cada solicitud requiere un método HTTP específico. El método esperado para cada punto final se puede consultar en la Referencia de la API REST o en la interfaz de usuario de Swagger .

En general, el método utilizado corresponde al cambio de estado esperado realizado.

Método

Descripción

Ejemplo

CONSEGUIR

Se utiliza solo para leer datos y no para modificarlos.

.../{dn_del_emisor}/{número_de_serie_del_certificado_hexadecimal}/estado_de_revocación

PONER

Se utiliza en operaciones que actualizan algún estado de entidad.

.../{dn_del_emisor}/{número_de_serie_del_certificado_hexadecimal}/revocar

CORREO

Se utiliza en operaciones que crean alguna entidad.

.../almacén de claves de inscripción

BORRAR

Se utiliza en operaciones que eliminan alguna entidad.

.../endentity{nombre_de_endentity}

Cuerpo de la solicitud

<p Como se mencionó, algunos puntos finales aceptan un cuerpo de solicitud que contiene los datos de entrada deseados. Los cuerpos de solicitud solo deben contener datos en formato JSON y el encabezado Content-Type: application/json debe estar configurado en la solicitud para que esta sea aceptada. Todos los campos de entrada (no los valores) deben tener el formato snake_case, por ejemplo, "key_alg" en lugar de "keyAlg" o "key alg".

El siguiente ejemplo muestra una solicitud para inscribir un almacén de claves (usando cURL):

curl -X POST -H 'Content-Type: application/json' -i 'https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/enrollkeystore' --data '{
"username" : "testUser" ,
"password" : "foo123" ,
"key_alg" : "RSA" ,
"key_spec" : "2048"
}'

Respuestas

Al integrarse con la API REST, la información más relevante en la respuesta es la línea de estado (código de estado HTTP), el encabezado Content-Type y el cuerpo de la respuesta.

Códigos de estado

Cualquier código de respuesta entre 2xx y 3xx se considera exitoso. Esto significa que el servidor aceptó la solicitud y envió la respuesta correspondiente. El código de respuesta típico de una solicitud GET sería 200 - OK . Cuando la operación requiere la aprobación de otro administrador, la respuesta será 201 - Accepted , lo que significa que la solicitud se aceptó correctamente y está pendiente de aprobación.

Los códigos de respuesta entre 4xx y 5xx deben considerarse errores. Puede tratarse de un fallo de autenticación, un conflicto o un error general del servidor. Por ejemplo, solicitar una operación no permitida con su certificado de cliente específico generará el error 403 - No autorizado , probablemente seguido de un mensaje de respuesta en el cuerpo de la respuesta.

Para obtener una lista completa de los códigos que pueden aparecer al interactuar con la API, consulte Códigos de estado .

Cuerpo de respuesta

El tipo de contenido de la respuesta se puede determinar mediante el encabezado Content-Type y la mayoría de los endpoints siempre devolverán application/json . Las excepciones incluyen, por ejemplo, llamar a .../ca/{issuer_dn}/certificate/download , que devuelve un certificado .pem con transmisión de bytes. En este caso, se utiliza el encabezado comodín */* . Todas las solicitudes que lleguen al servidor, independientemente del código de respuesta, recuperarán un cuerpo de respuesta. Cualquier respuesta a una solicitud exitosa contendrá un cuerpo con la información solicitada, por ejemplo:

curl -X GET -i 'https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/CN%3DManagementCA%2CO%3DEJBCA%20Sample%2CC%3DSE/4b0b0ceb7a8e5f1f/revocationstatus'

Devuelve el siguiente cuerpo JSON (si se encuentra el certificado):

{
"issuer_dn" : "CN=ManagementCA,O=EJBCA Sample,C=SE" ,
"serial_number" : "4b0b0ceb7a8e5f1f" ,
"revocation_reason" : "KEY_COMPROMISE" ,
"revocation_date" : "2018-06-27T08:07:52Z" ,
"revoked" : true
}

En caso de error, se devuelve un cuerpo de respuesta que contiene el código de estado (además del encabezado) y un mensaje de error apropiado.

Por ejemplo, si la solicitud anterior se realizó para una CA que no existe, el cliente podría esperar una respuesta como:

{
"error_code" : 404 ,
"error_message" : "CA 'CN=NonExistingCA,O=EJBCA Sample,C=SE' does not exist."
}

Si se produce un error completamente inesperado, el servidor responderá con el error 500 - Error general . En este caso, verifique el contenido de la solicitud y, a continuación, solicite al administrador de la CA que revise el registro del servidor.

Autenticación

La API REST requiere autenticación con certificado de cliente u OAuth, al igual que la interfaz gráfica de administración. Si tiene un certificado de cliente de la interfaz gráfica de administración en funcionamiento, también debería poder usarlo para la API REST. La forma en que se transmite el certificado con la solicitud depende de su entorno de integración. Para verificar la respuesta y la autenticación del servidor, intente acceder a la API a través de cualquier navegador web con su certificado de cliente:

https: //[DOMAIN_NAME]:[PORT]/ejbca/ejbca-rest-api/v1/ca/version

También puede utilizar cURL o una herramienta similar especificando --cert y --key.

Si no se proporciona ningún certificado o se proporciona un certificado no válido, lo más probable es que aparezca un error de "Certificado incorrecto". Sin embargo, si se intenta solicitar un recurso con privilegios superiores a los de un certificado válido, la respuesta contendrá un cuerpo de respuesta en formato JSON con el código de estado 403 - No autorizado, seguido del mensaje correspondiente. Para obtener más información, consulte Códigos de estado .

EMPRESA Esta es una característica de EJBCA Enterprise.

Para usar OAuth, se requiere un encabezado que contenga la autorización: Bearer {token}. El token debe obtenerse del proveedor de identidad que EJBCA está configurado para usar con OAuth. Un ejemplo de uso de cURL o una herramienta similar sería el siguiente:

curl -H "Authorization: Bearer {23dues7r3s93sc}" -H "accept: application/json" -X GET "https://[DOMAIN_NAME]:[PORT]/ejbca/ejbca-rest-api/v1/ca/version"

Depuración de la API REST

De forma predeterminada, EJBCA registra información básica sobre las solicitudes entrantes y el nivel INFO.

La siguiente información se registra en el nivel de registro INFO:

  • dirección remota

  • Valor del encabezado "X-Forwarded-For"

Ejemplo:

13 : 31 : 07 , 976 INFO [org.ejbca.ui.web.rest.api.config.RestLoggingFilter] ( task- default 10 ) GET https: //localhost:8443/ejbca/ejbca-rest-api/v1/ca/CN=Management%20CA,O=PK,C=SE/certificate/download received from 127.0.0.1 X-Forwarded-For: null

También es posible hacer que EJBCA registre las solicitudes y respuestas completas en el nivel TRACE.

La siguiente información se registra en el nivel TRACE:

  • solicitud y respuesta

  • tiempo empleado por solicitud, es decir, hora de finalización - hora de inicio

Dado que habilitar el registro de TRACE globalmente para todo EJBCA puede resultar en un registro excesivo, es posible habilitarlo solo para RestLoggingFilter . En JBoss/WildFly, esto se realiza con comandos simples en jboss-cli:

/subsystem=logging/logger=org.ejbca.ui.web.rest.api.config:add
/subsystem=logging/logger=org.ejbca.ui.web.rest.api.config:write-attribute(name=level, value=TRACE)

El ejemplo de registro de TRACE para una solicitud simple es el siguiente:

curl -X GET "https://localhost:8443/ejbca/ejbca-rest-api/v1/ca/CN=Management%20CA,O=PK,C=SE/certificate/download" --insecure --cert cert-superadmin.pem --key key-superadmin.pem
2018 - 08 - 07 13 : 31 : 08 , 038 TRACE [org.ejbca.ui.web.rest.api.config.RestLoggingFilter] ( task- default 10 ) GET https: //localhost:8443/ejbca/ejbca-rest-api/v1/ca/CN=Management%20CA,O=PK,C=SE/certificate/download received from 127.0.0.1 X-Forwarded-For: null
Request headers:
Accept: */*
User-Agent: curl/ 7.47 . 0
Host: localhost: 8443
Request data:
Response data:
Subject: CN=Management CA,O=PK,C=SE
Issuer: CN=Management CA,O=PK,C=SE
-----BEGIN CERTIFICATE-----
MIIDTzCCAjegAwIBAgIIbbifeqpPKLcwDQYJKoZIhvcNAQELBQAwNTEWMBQGA1UE
<snip>
xdd9ycYOyym2nvM+SPydHlK8dAqwwXzICFFOCRADsQNakVU=
-----END CERTIFICATE-----
Time taken: 62ms

Códigos de estado

Los códigos de estado de la API se exponen en códigos de respuesta HTTP estándar y mensajes con formato JSON. Por ejemplo, el siguiente ejemplo muestra un error HTTP 403:

{
"error_code" : 403 ,
"error_message" : "Not authorized to resource /administrator."
}

El código de respuesta también estará disponible en la línea de estado de la respuesta HTTP. La siguiente tabla describe los códigos de estado que pueden ser respuestas "esperadas" de la API REST y algunas posibles razones.

Código de estado HTTP

Descripción general

Contexto de API REST de EJBCA

200

DE ACUERDO

Solicitud HTTP exitosa; se espera un cuerpo de respuesta correcto. Normalmente se recibe de una solicitud GET exitosa.

201

Creado

Solicitud HTTP exitosa. Se ha creado alguna entidad, por ejemplo, se ha registrado un certificado. Normalmente se recibe tras una solicitud POST exitosa.

202

Aceptado

Solicitud aceptada por el servidor, pero pendiente de procesamiento. Probablemente esté esperando la aprobación del administrador.

400

Solicitud incorrecta

Un error común que puede ser causado por muchas condiciones como:

  • parámetros de entrada no válidos / cuerpo JSON en la solicitud

  • un alias no válido en la ruta de la solicitud

  • La CA solicitada no existe

  • Error al crear o renovar un certificado debido a que la solicitud no cumple con las condiciones previas
    (esto puede ser muchas cosas, como intentar renovar con la misma clave pública cuando no está permitido, etc., etc.)

Las pistas sobre qué causó el problema generalmente se devuelven en la parte del mensaje de la respuesta de error HTTP y se registran en el archivo de registro del servidor para los administradores.

403

Prohibido

Solicitud aceptada pero la operación es rechazada debido a privilegios insuficientes, funciones deshabilitadas, etc.

404

Extraviado

EJBCA no encontró la entidad solicitada. Esto podría ocurrir si la entrada hace referencia a una entidad inexistente, como un usuario o una CA.

409

Conflicto

Se produjo un conflicto al procesar la solicitud, por ejemplo, al intentar revocar un certificado ya revocado.

413

Carga útil demasiado grande

La solicitud es mayor de lo que el servidor puede procesar. Esto no debería ocurrir al usar la API según lo previsto.

422

Entidad no procesable

Solicitud bien formada, pero no se pudo procesar debido, por ejemplo, a errores semánticos. Esto podría ocurrir si el algoritmo de clave no es válido, la validez no es válida, etc.

500

Error Interno del Servidor

Error inesperado al llamar a la API. Para más información, consulte el registro del servidor (Administrador de CA).

503

Servicio No Disponible

La razón posible podría ser que la CA esté fuera de línea, el registro CT no esté disponible, etc.

Versión de API

Todos los recursos REST de EJBCA utilizan versiones URI.

Ejemplo: https://hostname:8443/ejbca/ejbca-rest-api/ v1 /certificate/search en donde v1 define la versión de la API.

La versión de la API no cambiará con las nuevas versiones de EJBCA a menos que:

  • Se ha cambiado cualquier parámetro de punto final requerido.

  • El formato de respuesta de cualquier punto final ha cambiado.

Generalmente, se evitarán estos cambios en los endpoints existentes, ya que interrumpirían las integraciones de clientes existentes. Si se realiza un cambio de este tipo, se incluirá en una versión principal de EJBCA y se documentará claramente en las Notas de Actualización de EJBCA.

Sin embargo, la API evoluciona continuamente con nuevos endpoints. Estos nuevos endpoints no afectan la versión de la API, ni la adición de campos adicionales a una respuesta existente (dentro del mismo formato).

Ejemplos

Generar un CSR y solicitar un certificado usando Bash

Puede usar OpenSSL, jq y cURL ( versión >7.57) para crear una clave y una CSR, crear una carga JSON que contenga la CSR y luego inscribirse para obtener un certificado de servidor TLS usando el archivo de configuración y el script a continuación.

Ejemplo de archivo de configuración

csr.conf
[req]
distinguished_name = req_distinguished_name
req_extensions = v3_req
prompt = no
[req_distinguished_name]
C = SE
O = PrimeKey Solutions AB
OU = Infra
CN = primekey.com
[v3_req]
keyUsage = keyEncipherment, digitalSignature
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS. = primekey.com 1

Ejemplo de script

El script pkcs10enroll.sh genera un nuevo CSR si aún no existe uno, solicita un certificado de EJBCA y luego imprime la respuesta JSON en stdout.

Para habilitar el uso de certificados autofirmados en desarrollo, agregue -k a las opciones de curl. Para ver el mensaje de error de curl, elimine -s .

pkcs10enroll.sh
#!/bin/sh
# Before running this script you need to do the following:
# 1. If you are contacting the CA directly:
#
# Enable the REST API in System Configuration -> Protocol Configuration.
#
# If you are contacting an external RA, you should enable the REST API for
# the peer role on the CA.
hostname = "172.16.31.14"
# 2. Specify profiles, CA and end entity to use for issuance
cert_profile_name= "staging-cert"
ee_profile_name= "staging-ee"
ca_name= "Issuing CA"
# This user will be created if it does not exist. The status of an existing
# end entity will be set to NEW automatically.
username= "pkcs10enroll_user"
# If the user already exists, specify the enrollment code here
enrollment_code= "foo123"
# 3. Adjust the variable $client_cert to point to a client certificate.
client_cert= "/opt/jboss/p12/SuperAdmin.p12:foo123"
if [ ! -f 'server.csr' ]; then
openssl req -new -out server.csr -newkey rsa:2048 \
-nodes -sha256 -keyout server.key \
-config csr.conf > /dev/null 2>&1
fi
csr=$( cat server.csr)
template= '{"certificate_request":$csr, "certificate_profile_name":$cp, "end_entity_profile_name":$eep, "certificate_authority_name":$ca, "username":$ee, "password":$pwd}'
json_payload=$(jq -n \
--arg csr "$csr" \
--arg cp "$cert_profile_name" \
--arg eep "$ee_profile_name" \
--arg ca "$ca_name" \
--arg ee "$username" \
--arg pwd "$enrollment_code" \
"$template" )
curl -X POST -s \
--cert- type P12 \
--cert "$client_cert" \
-H 'Content-Type: application/json' \
--data "$json_payload" \
"https://$hostname/ejbca/ejbca-rest-api/v1/certificate/pkcs10enroll" \
| jq .

Una solicitud JSON (para usar en swagger-ui, por ejemplo) se vería así, un CSR PKCS#10 simple usando \n como saltos de línea:

{
"certificate_request":"-----BEGIN CERTIFICATE REQUEST-----\nMIIChTCCAW0CAQAwQDELMAkGA1UEBhMCU0UxDjAMBgNVBAgMBVNvbG5hMREwDwYD\nVQQKDAhQcmltZUtleTEOMAwGA1UEAwwFVG9tYXMwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQDfOpmUDnUsilYoaYpHUGN9AvAkK2AdHoYz4cTkKD4kPPvq\nErRdayyGWiuKrmhH6v+jPvh5ZYQoqL2viSTIkcvr7BIo9pgqSVswxvC5v4GGy3R4\nnme0El27oB5X0AJl3X5STT5GwIWw66XHcTeg1ux62bfY/N1RhiHanFOZ00DokPyW\n/s+dGcnZ9kBC5s5jcEEEwcGXCyKuyCoy60Z87asOraCsYeRlq3qqdms0BZEM7lLK\n7oP4HjIpk9VSLYihGlFsbophw96gNGtYjorX//CYvuyckUpA9TLdfx8IoQSiKlsJ\nCDdMeDXnkqOZAmXj3xos3qm1VJV2J9AVggzQ1SUnAgMBAAGgADANBgkqhkiG9w0B\nAQsFAAOCAQEAGcK8aMvmdhsTeCv+D1R21Bjc5fb+dmrXcYdR4RI8roW4GZDqGdBU\n8bYDZfO0SnV0q6m23G6upVhtYpzOrVcDaiQ4iFvGQkz8pfErZ+qqwZhE6yvbc+2p\n0BVuIIePbgdAW17acxkOF4p0Z5TkNazdNwePyjW8dfUvarVX//AA48l66bUXu6IM\nX2LU/OY1hcLETlAqV2o1iDPRsOTnF2OpV8FdmpBhD7VUa78h8n3w3l+WdmaAhcy4\njItzjKHi5CEoJ3s15Yo4zuwZt2g+bmGGfBqGcSKkPAlsQ+A79DMwzJXLN/Cs/joY\ngwObGYEkQqkX1DGjDNzYyw+RtvdzJV8shQ==\n-----END CERTIFICATE REQUEST-----",
"certificate_profile_name":"Client",
"end_entity_profile_name":"User",
"certificate_authority_name":"ManagementCA",
"username":"myuser",
"password":"foo123",
"include_chain":true,
"email": "useremail@domain.com"
}

correo electrónico en pkcs10enroll

A partir de la versión 7.10.0, se debe mencionar el correo electrónico en la solicitud pkcs10enroll de la interfaz REST. Esto permite actualizar la información de la entidad final. Si no se menciona, el correo electrónico del usuario se establecerá como nulo en la base de datos.


con el comando curl resultante (usando superadmin.p12 para la autenticación RA):

curl -k --cert-type P12 --cert p12/superadmin.p12:ejbca -X POST "https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/pkcs10enroll" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"certificate_request\":\"-----BEGIN CERTIFICATE REQUEST-----\nMIIChTCCAW0CAQAwQDELMAkGA1UEBhMCU0UxDjAMBgNVBAgMBVNvbG5hMREwDwYD\nVQQKDAhQcmltZUtleTEOMAwGA1UEAwwFVG9tYXMwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQDfOpmUDnUsilYoaYpHUGN9AvAkK2AdHoYz4cTkKD4kPPvq\nErRdayyGWiuKrmhH6v+jPvh5ZYQoqL2viSTIkcvr7BIo9pgqSVswxvC5v4GGy3R4\nnme0El27oB5X0AJl3X5STT5GwIWw66XHcTeg1ux62bfY/N1RhiHanFOZ00DokPyW\n/s+dGcnZ9kBC5s5jcEEEwcGXCyKuyCoy60Z87asOraCsYeRlq3qqdms0BZEM7lLK\n7oP4HjIpk9VSLYihGlFsbophw96gNGtYjorX//CYvuyckUpA9TLdfx8IoQSiKlsJ\nCDdMeDXnkqOZAmXj3xos3qm1VJV2J9AVggzQ1SUnAgMBAAGgADANBgkqhkiG9w0B\nAQsFAAOCAQEAGcK8aMvmdhsTeCv+D1R21Bjc5fb+dmrXcYdR4RI8roW4GZDqGdBU\n8bYDZfO0SnV0q6m23G6upVhtYpzOrVcDaiQ4iFvGQkz8pfErZ+qqwZhE6yvbc+2p\n0BVuIIePbgdAW17acxkOF4p0Z5TkNazdNwePyjW8dfUvarVX//AA48l66bUXu6IM\nX2LU/OY1hcLETlAqV2o1iDPRsOTnF2OpV8FdmpBhD7VUa78h8n3w3l+WdmaAhcy4\njItzjKHi5CEoJ3s15Yo4zuwZt2g+bmGGfBqGcSKkPAlsQ+A79DMwzJXLN/Cs/joY\ngwObGYEkQqkX1DGjDNzYyw+RtvdzJV8shQ==\n-----END CERTIFICATE REQUEST-----\",\"certificate_profile_name\":\"Client\",\"end_entity_profile_name\":\"User\",\"certificate_authority_name\":\"ManagementCA\",\"username\":\"myuser\",\"password\":\"foo123\",\"include_chain\":true,\"email\": \"useremail@domain.com\"}"

Ejemplo de flujo de trabajo de revocación

Siga el ejemplo a continuación para verificar primero el estado de revocación de un certificado y luego revocarlo.

En este ejemplo, el DN del certificado es CN=CA1 y el número de serie (en hexadecimal) es 5CB3D42686039768D973E5694BF205377AF6 .

  1. Para comprobar el estado de revocación del certificado, llame al método REST GET /v1/certificate/{issuer_dn}/{certificate_serial_number}/revocationstatus :

    curl -X GET -s \
    --cert-type P12 \
    --cert "/opt/jboss/p12/SuperAdmin.p12:foo123" \
    -H "accept: application/json"
    "https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/CN%3DCA1/5CB3D42686039768D973E5694BF205377AF6/revocationstatus"
  2. Desde la respuesta a continuación, puede confirmar que el certificado está activo.

    {
    "issuer_dn" : "CN=CA1" ,
    "serial_number" : "5CB3D42686039768D973E5694BF205377AF6" ,
    "revocation_reason" : "NOT_REVOKED" ,
    "revoked" : false
    }
  3. Para revocar el certificado, llame al método REST PUT /v1/certificate/{issuer_dn}/{certificate_serial_number}/revoke :

    curl -X PUT -s \
    --cert-type P12 \
    --cert "/opt/jboss/p12/SuperAdmin.p12:foo123" \
    -H "accept: application/json"
    "https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/CN%3DCA1/5CB3D42686039768D973E5694BF205377AF6/revoke?reason=KEY_COMPROMISE"
  4. Confirme con la respuesta que el certificado se ha revocado correctamente:

    {
    "issuer_dn" : "CN=HT_REMOVAL_CA" ,
    "serial_number" : "5CB3D42686039768D973E5694BF205377AF6" ,
    "revocation_reason" : "KEY_COMPROMISE" ,
    "revocation_date" : "2019-05-27T15:02:56Z" ,
    "message" : "Successfully revoked" ,
    "revoked" : true
    }

Solicitar un almacén de claves PKCS#12 mediante Python

Para solicitar un almacén de claves PKCS#12 mediante Python, haga lo siguiente:

  1. Instale el módulo requests_pkcs12 usando pip.

    requests_pkcs12 install pip3
  2. Autentíquese con el certificado de cliente almacenado en superadmin.p12 y solicite un archivo PKCS12 para la entidad final python .

    import json
    from requests_pkcs12 import post
    response = post( 'https://myca:8443/ejbca/ejbca-rest-api/v1/certificate/enrollkeystore' ,
    json = {
    'username' : 'python' ,
    'password' : 'foo123' ,
    'key_alg' : 'RSA' ,
    'key_spec' : '2048'
    },
    headers = {
    'content-type' : 'application/json'
    },
    pkcs12_filename = '/srv/superadmin.p12' ,
    pkcs12_password = 'foo123' ,
    verify = '/srv/truststore.pem' )
    print (json.dumps(json.loads(response.content), indent = 4 , sort_keys = True ))

Solicitar un almacén de claves PKCS#12 mediante Node.js

Para solicitar un almacén de claves PKCS#12 mediante Node.js, haga lo siguiente:

  1. Instale el módulo node.js llamado node-fetch.

    npm install node-fetch
  2. Crea un script que se parezca a esto:

    const fs = require( 'fs' );
    const https = require( 'https' );
    const fetch = require( 'node-fetch' );
    // Load the keystore used to authenticate to the REST API
    const pfx = fs.readFileSync( 'RA_Administrator.p12' );
    const passphrase = 'foo123' ;
    const agent = https.Agent({ pfx, passphrase });
    // Load the enrollment code for the end entity
    const enrollmentCode = 'foo123'
    // Name of the end entity
    const deviceName = 'Company Device 1'
    // Request renewal of the device certificate
    fetch( 'https://nautilus:8443/ejbca/ejbca-rest-api/v1/endentity/' + deviceName + '/setstatus' , {
    agent: agent,
    method: 'post' ,
    body: JSON.stringify({
    "password" : enrollmentCode,
    "token" : "P12" ,
    "status" : "NEW"
    }),
    headers: { 'Content-Type' : 'application/json' },
    })
    .then(res => {
    if (res.status != 200) {
    console.log( 'Renewal failed with status code ' + res.status + '.' )
    } else {
    console.log( 'Renewal succeeded! Requesting new device certificate from EJBCA...' )
    fetch( 'https://nautilus:8443/ejbca/ejbca-rest-api/v1/certificate/enrollkeystore' , {
    agent: agent,
    method: 'post' ,
    body: JSON.stringify({
    "username" : deviceName,
    "password" : enrollmentCode,
    "key_alg" : "RSA" ,
    "key_spec" : "2048"
    }),
    headers: { 'Content-Type' : 'application/json' },
    })
    .then(res => res.json())
    .then(json => console.log(json))
    . catch (error => console.log(error))
    }
    })
    . catch (error => console.log(error))

Búsqueda de certificados

Para buscar certificados con múltiples criterios de búsqueda, utilice el método de búsqueda .

Ejemplo de solicitud de búsqueda JSON

A continuación se muestra un ejemplo de solicitud de búsqueda JSON para buscar certificados ACTIVOS para el usuario superadmin , limitando la búsqueda para devolver un máximo de 10 certificados:

{
"max_number_of_results" : 10 ,
"criteria" : [
{
"property" : "QUERY" ,
"value" : "superadmin" ,
"operation" : "EQUAL"
},
{
"property" : "STATUS" ,
"value" : "CERT_ACTIVE" ,
"operation" : "EQUAL"
}
]
}

Para buscar campos DN o altName, por ejemplo, buscando un máximo de 10 certificados emitidos a un usuario con un nombre común como 'Nombre Apellido', utilice lo siguiente:

{
"max_number_of_results" : 10 ,
"criteria" : [
{
"property" : "QUERY" ,
"value" : "Firstname Lastname" ,
"operation" : "LIKE"
},
{
"property" : "STATUS" ,
"value" : "CERT_ACTIVE" ,
"operation" : "EQUAL"
}
]
}

Para buscar certificados según su número de serie, utilice una consulta similar a la siguiente. El valor de la propiedad QUERY es el número de serie del certificado en formato hexadecimal o decimal:

{
"max_number_of_results" : 10 ,
"criteria" : [
{
"property" : "QUERY" ,
"value" : "404762757874990468244089956248237274051937985705" ,
"operation" : "LIKE"
},
{
"property" : "STATUS" ,
"value" : "CERT_ACTIVE" ,
"operation" : "EQUAL"
}
]
}


Búsqueda de certificados versión 2

Para buscar certificados con múltiples criterios de búsqueda, paginación y clasificación, utilice el método de búsqueda versión 2.

Ejemplo de solicitud de búsqueda JSON

A continuación se muestra un ejemplo de solicitud de búsqueda JSON para buscar certificados ACTIVOS , devolviendo la primera página con un tamaño de página de 1000, limitando la búsqueda para devolver un máximo de 1000 certificados, ordenados por la última hora de actualización:

{
"pagination" : {
"page_size" : 1000 ,
"current_page" : 1
},
 "sort" : {
"property" : "UPDATE_TIME" ,
"operation" : "ASC"
},
"criteria" : [
{
"property" : "STATUS" ,
"value" : "CERT_ACTIVE" ,
"operation" : "EQUAL"
}
]
}

Cada consulta debe contener al menos un criterio. La paginación y la ordenación son opcionales. Si falta la paginación, se devuelve el número total de certificados para los criterios especificados. En este caso, la ordenación se ignora si está presente en la solicitud. page_size y current_page deben ser mayores que 0. La propiedad de ordenación puede ser una de las siguientes:

  • NOMBRE DE USUARIO

  • DN_EMISOR

  • DN_SUJETO

  • ID DE VINCULACIÓN DE CUENTA EXTERNA

  • PERFIL_DE_ENTIDAD_FINAL

  • PERFIL_DE_CERTIFICADO

  • ESTADO

  • ETIQUETA

  • TIPO

  • HORA DE ACTUALIZACIÓN

  • FECHA DE EMISIÓN

  • FECHA DE CADUCIDAD o

  • FECHA DE REVOCACIÓN

Búsqueda de entidades finales

Se pueden buscar entidades finales mediante la API v1. Los criterios de búsqueda admitidos son:

  • CONSULTA

  • PERFIL_DE_ENTIDAD_FINAL

  • PERFIL_DE_CERTIFICADO

  • CA, ESTADO

  • MODIFICADO ANTES

  • MODIFICADO DESPUÉS

Tenga en cuenta que QUERY permite realizar búsquedas con el nombre de la entidad final, el nombre distinguido del sujeto y el nombre alternativo del sujeto.

Entidades finales de búsqueda v1
{
"max_number_of_results" : 10 ,
"current_page" : 2 ,
"criteria" : [
{
"property" : "QUERY" ,
"value" : "exampleUser" ,
"operation" : "LIKE"
},
{
"property" : "CA" ,
"value" : "exampleCA" ,
"operation" : "EQUAL"
}
]
}

Búsqueda de entidades finales versión 2

La API de búsqueda v2 también admite la ordenación. La ordenación se permite mediante:

  • NOMBRE DE USUARIO

  • DN_SUJETO

  • NOMBRE ALT. DEL ASUNTO

  • PERFIL_DE_ENTIDAD_FINAL

  • PERFIL_DE_CERTIFICADO

  • ESTADO

  • HORA DE ACTUALIZACIÓN

  • HORA DE CREACIÓN

Los resultados se pueden ordenar de forma ascendente (ASC) o descendente (DESC). Tenga en cuenta que en la búsqueda v2, el parámetro current_page debe empezar en 1 y, si se necesitan más resultados, el número de página debe incrementarse secuencialmente en futuras consultas. No se permite omitir páginas ni acceder a páginas arbitrarias al buscar con este punto final.

entidades finales de búsqueda v2
{
"max_number_of_results" : 10 ,
"current_page" : 2 ,
"criteria" : [
{
"property" : "QUERY" ,
"value" : "exampleUser" ,
"operation" : "LIKE"
},
{
"property" : "CA" ,
"value" : "exampleCA" ,
"operation" : "EQUAL"
}
],
"sort_operation" : {
"property" : "CREATED_TIME" ,
"operation" : "ASC"
}
}


Ejemplo de comando de búsqueda cURL

A continuación se muestra un ejemplo de comando cURL para buscar certificados ACTIVOS para el usuario superadmin , limitando la búsqueda para devolver un máximo de 10 certificados:

curl -X POST "https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/search" \
-H "accept: application/json" -H "Content-Type: application/json" \
-d "{ \"max_number_of_results\": 10, \"criteria\": [ { \"property\": \"QUERY\", \"value\": \"tomastest1.primekey.com\", \"operation\": \"EQUAL\" }, { \"property\": \"STATUS\", \"value\": \"CERT_ACTIVE\", \"operation\": \"EQUAL\" } ]}"

Agregar entidad final

EMPRESA Esta es una característica de EJBCA Enterprise.

Para agregar una entidad final usando el punto final endentity , se puede usar un JSON como este:

{
"username": "tomas44",
"password": "foo123",
"subject_dn": "CN=tomas44",
"subject_alt_name": "",
"email": "",
"extension_data": [
{
"name": "foo",
"value": "bar"
}
],
"ca_name": "ManagementCA",
"certificate_profile_name": "Client",
"end_entity_profile_name": "User",
"token": "P12"
}

y cURL:

curl -X POST "https://localhost:8443/ejbca/ejbca-rest-api/v1/endentity" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"username\": \"tomas44\", \"password\": \"foo123\", \"subject_dn\": \"CN=tomas44\", \"subject_alt_name\": \"\", \"email\": \"\", \"extension_data\": [ { \"name\": \"foo\", \"value\": \"bar\" } ], \"ca_name\": \"ManagementCA\", \"certificate_profile_name\": \"Client\", \"end_entity_profile_name\": \"User\", \"token\": \"P12\"}"

Después de agregar una entidad final como esa, puede inscribirse en un almacén de claves PKCS#12 con el punto final de certificado/enrollkeystore :

{
"username": "tomas44",
"password": "foo123",
"key_alg": "RSA",
"key_spec": "2048"
}

y cURL:

curl -X POST "https://localhost:8443/ejbca/ejbca-rest-api/v1/certificate/enrollkeystore" -H "accept: application/json" -H "Content-Type: application/json" -d "{ \"username\": \"tomas44\", \"password\": \"foo123\", \"key_alg\": \"RSA\", \"key_spec\": \"2048\"}"

Agregar datos de extensión

Para el número de serie del certificado, el parámetro se ve así: CERTIFICATESERIALNUMBER=<serial number> . Empieza el número con '0x' para indicar que es hexadecimal.

Ejemplo:

CERTIFICATESERIALNUMBER= 8642378462375036 CERTIFICATESERIALNUMBER= 0x5a53875acdaf24

Para la extensión del certificado, el parámetro se ve así: <oid> [.<type>] =value . La clave '1.2.3.4' es la misma que '1.2.3.4.value'.

Ejemplo:

1.2 . 840.113634 . 100.6 . 1.1 =00aa00bb 1.2 . 3.4 .value1= 1234 1.2 . 3.4 .value2=abcdef

Para la Declaración de Control de Calidad ETSI PSD2, los parámetros (todos obligatorios) son: QCETSIPSD2ROLESOFPSP=oid;name', QCETSIPSD2NCANAME='Nombre de NCA', QCETSIPSD2NCAID='ID de NCA '. Un parámetro opcional de identificador de organización del foro CAB (como parte de la información extendida) proporcionado al comando con un formato de ejemplo similar al siguiente:

CABFORGANIZATIONIDENTIFIER=VATSE- 123456789

A continuación se muestra un código de ejemplo sobre cómo agregar información extendida en la solicitud WS:

ei.add( new ExtendedInformationWS (ExtendedInformation.CUSTOMDATA+ExtendedInformation.CUSTOM_REVOCATIONREASON,
Integer.toString(RevokeStatus.REVOKATION_REASON_CERTIFICATEHOLD)));
ei.add( new ExtendedInformationWS (ExtendedInformation.SUBJECTDIRATTRIBUTES, "DATEOFBIRTH=19761123" ));
user.setExtendedInformation(ei);
<p >que se traduce como:

customdata_REVOCATIONREASON=REVOKATION_REASON_UNSPECIFIED
subjectdirattributes= "DATEOFBIRTH=19761123"

Se pueden encontrar otros atributos en ExtendedInformation, por ejemplo:

STARTTIME= "May 26, 2009 9:52 AM" or "days:hours:minutes"
ENDTIME=like above

Exportación de configuración con ConfigDump

EMPRESA Esta es una característica de EJBCA Enterprise.

La exportación e importación de configuraciones admiten parámetros como ignoreerrors, include, exclude , etc. Para obtener más información sobre los parámetros disponibles, consulte Swagger UI , la referencia de la API REST generada o la herramienta ConfigDump .

La configuración se puede exportar de diferentes maneras: la configuración completa, por tipo, por tipo y configuración, o como un archivo ZIP que contiene la exportación ConfigDump con formato YAML.

Exportar toda la configuración

Ejemplo de comando cURL para exportar toda la configuración en formato JSON:

curl -X GET "https://localhost:8443/ejbca/ejbca-rest-api/v1/configdump?ignoreerrors=true&defaults=false&externalcas=false" \
-H "accept: application/json"

Ejemplo de comando cURL para exportar toda la configuración como un archivo ZIP:

curl -X GET "https://localhost:8443/ejbca/ejbca-rest-api/v1/configdump/configdump.zip?ignoreerrors=false&defaults=false&externalcas=false" \
-H "accept: application/zip"

Exportación de publicadores mediante ConfigDump (recurso /configdump/{type})

Se pueden usar diferentes tipos (PUBLISHER para editores, CRYPTOTOKEN para tokens criptográficos, etc.). Para obtener una lista completa de tipos, consulte las descripciones generadas en la referencia de la API REST .

curl -X GET "https://localhost:8443/ejbca/ejbca-rest-api/v1/configdump/PUBLISHER?ignoreerrors=false&defaults=false&externalcas=false" \
-H "accept: application/json"

Exportar un nombre de publicador "test" (recurso /configdump/{type}/{setting})

curl -X GET "https://localhost:8443/ejbca/ejbca-rest-api/v1/configdump/PUBLISHER/test?ignoreerrors=false&defaults=false" \
-H "accept: application/json"

Importar configuración con ConfigDump

EMPRESA Esta es una característica de EJBCA Enterprise.

Los datos JSON para la parte del cuerpo de una solicitud POST de importación siguen la convención: los valores de los atributos son exactamente los mismos que cuando se importa o exporta a través de la CLI de ConfigDump con archivos YAML.

{
"<configuration type>" : {
"<configuration name>" : {
"<attribute field>" : "<value>" ,
},
"<configuration name>" : {
"<attribute field>" : "<value>" ,
}
}
}

Un ejemplo de cuerpo JSON para importar un único perfil de aprobación:

{
"approval-profiles" : {
"Test Approval Profile" : {
"Object Type" : "Approval Profile" ,
"Version" : 1,
"ID" : 526448739,
"Type" : "ACCUMULATIVE_APPROVAL" ,
"Name" : "Test Approval Profile" ,
"Approval Expiration Period" : "8h" ,
"Request Expiration Period" : "8h" ,
"Max Extension Time" : "0d" ,
"Allow Self-Approved Request Editing" : false ,
"Number of Approvals Required" : 1
}
}
}

Y el comando cURL esperado para el cuerpo JSON anterior:

curl -X POST "https://localhost:8443/ejbca/ejbca-rest-api/v1/configdump?ignoreerrors=false&initialize=false&continue=false&overwrite=abort&resolve=abort" \
-H "accept: application/json" -H "Content-Type: application/json" \
-d "{ \"approval-profiles\": { \"Test Approval Profile\": { \"Object Type\": \"Approval Profile\", \"Version\": 1, \"ID\": 526448739, \"Type\": \"ACCUMULATIVE_APPROVAL\", \"Name\": \"Test Approval Profile\", \"Approval Expiration Period\": \"8h\", \"Request Expiration Period\": \"8h\", \"Max Extension Time\": \"0d\", \"Allow Self-Approved Request Editing\": false, \"Number of Approvals Required\": 1 } }}"

Importar una configuración de archivo ZIP

# Prepare the ZIP file
cd <working-directory>
zip -r configdump.zip .
# Example cURL command that uses above ZIP file (which has the folder/file structure an CLI ConfigDump would create)
curl -X POST "https://localhost:8443/ejbca/ejbca-rest-api/v1/configdump/configdump.zip" \
-H "accept: application/json" -H "Content-Type: multipart/form-data" \
-F "zipfile=@configdump.zip;type=application/zip" -F "overwrite=abort" -F "resolve=abort"

Solución de problemas

Codificación de solicitud de certificado

Una excepción como la siguiente puede deberse a un problema de codificación:

 IOException while decoding certificate request from PEM: -----END CERTIFICATE REQUEST

El problema se puede resolver reemplazando manualmente los saltos de línea con \n .

Cómo encontrar la causa de los códigos de error devueltos al cliente

Cuando recibe un mensaje de error, como HTTP 404 (BAD_REQUEST), la causa suele encontrarse en un mensaje devuelto como parte del error HTTP. La causa completa del error también suele estar visible en el archivo de registro del servidor para que la consulten los administradores.

Conversión de respuestas en formato DER a PEM

Los archivos DER binarios suelen tener extensiones .cer, .crt o .der, mientras que los archivos PEM se especifican estrictamente con encabezados PEM -----BEGIN / END CERTIFICATE----- y saltos de línea cada 64 caracteres. Más detalles en RFC7468 .

Algunas llamadas REST devuelven un certificado DER codificado en base64 dentro del cuerpo de la respuesta JSON para transferir los datos binarios en una estructura JSON. Se identifica con "response_format": "DER" en el propio JSON y se puede convertir a PEM cuando sea necesario.

Por ejemplo, después de una llamada exitosa a /v1/certificate/pkcs10enroll, la salida JSON contendrá un objeto de certificado en base64, que se puede extraer:

Procesa la respuesta JSON con jq para extraer los datos DER base64 y enviarlos a un archivo
jq -r .certificate response_1617122570566.json > certificate-base64.b64

Los datos base64 se pueden decodificar en el formato binario DER:

Descodificar el DER de nuevo a binario
openssl base64 -d -A - in certificate-base64.b64 -out certificate-bin.crt

Puedes convertirlo a PEM, por ejemplo con openssl:

Convertir DER a PEM usando openssl
openssl x509 -inform der - in certificate-bin.crt -out certificate.pem

y openssl también se puede utilizar para ir y venir entre PEM y DER:

También puedes convertir de PEM a DER usando openssl
openssl x509 -outform der - in certificate.pem -out certificate-bin.crt