Integración con Certificate Enroll
Descripción general
En este tutorial, aprenderás a integrar Certificate Enroll, un servicio de Redtrust que permite a las aplicaciones generar claves de forma segura y solicitar la emisión de certificados digitales desde un entorno controlado.
Este tutorial va dirigido a desarrolladores de partners de Redtrust con capacidad para emitir certificados y que quieran integrarse con el servicio de enrollment de Redtrust. Para seguir este tutorial, te será útil tener conocimientos básicos de las API HTTP, la autenticación mediante tokens bearer y los certificados digitales.
Contexto
Esta integración permite que un partner de Redtrust con capacidad de emitir certificados genere las claves de manera seguro en el servidor de Redtrust y se generen finalmente los certificados digitales.
Certificate Enroll gestiona todo el flujo de emisión, incluyendo:
- Autenticación del usuario
- Emisión de tokens
- Generación de claves
- Solicitud y renovación de certificados
El flujo de integración consta de dos fases principales:
-
Autenticación y obtención de token:
El usuario se autentica contra Redtrust, que emite un JWT (JSON Web Token) para autorizar el acceso. -
Generación de claves y emisión del certificado: Se usan los endpoints de la API para completar el proceso de emisión.
Antes de empezar
Para integrar el servicio, necesitas la siguiente información proporcionada por el cliente de Redtrust:
- Dirección IP o nombre del host del servidor Redtrust.
- El puerto utilizado para acceder a Sign Service (el valor predeterminado es
8082). - Nombre del usuario de aplicación para el servicio.
- (Opcional) Nombre de dominio.
También necesitas la siguiente información proporcionada por el operador de la aplicación cliente:
- URL de redirección donde se enviarán las credenciales temporales. Esta dirección debe estar registrada en Redtrust para autorizar el destino de redirección y es esencial para obtener el token final (JWT).
Paso 1: Autenticación y obtención del token
Solicitud de autenticación
Accede a la URL del servicio:
https://HOSTNAME_O_IP:PUERTO/authclient/auth/loginrequest?Consumer=RA_API&Domain=DOMINIO&RedirectUrl=URL_REDIRECCIÓN×tamp=TIMESTAMP&partner=NOMBRE_PARTNER&hmac=FIRMA_HMAC
Por ejemplo:
https://localhost:8082/authclient/auth/loginrequest?Consumer=RA_API&Domain=local.users&RedirectUrl=https%3A%2F%2Fgoogle.es%3Ftkn%3D×tamp=1744719496&partner=CA_DEMO&hmac=c360b2d221a55da777a5ba75264d8800ce6ebe89f41aa8b6da7e1a78bb601055`
Para ver la lista de parámetros compatibles, consulta Parámetros soportados.
Cabeceras obligatorias
Para garantizar la legitimidad de cada solicitud, debes incluir las siguientes cabeceras HTTP:
| Cabecera | Descripción |
|---|---|
x-partner-name | Nombre de la aplicación cliente, escrito en mayúsculas. Sirve para identificar y autorizar al partner que realiza la llamada. |
x-request-timestamp | Timestamp UNIX que indica cuándo se hace la solicitud. Ayuda a prevenir ataques de repetición. Consulta Unix TimeStamp - Epoch Converter. |
x-hmac-signature | Firma criptográfica que valida la solicitud. Se genera firmando el mensaje NOMBRE_PARTNER:TIMESTAMP_UNIX usando HMAC-SHA256 con una clave compartida. |
La cabecera x-hmac-signature permite al servidor verificar la autenticidad e integridad de la solicitud usando la clave secreta compartida. Toda solicitud que no tenga firma, esté mal formada o no sea válida será rechazada.
Redirección con token temporal
Si la autenticación se completa correctamente, el servidor redirige automáticamente al usuario a la URL proporcionada incluyendo el parámetro tkn:
https://cliente.com?tkn=TOKEN_TEMPORAL
Tu aplicación debe interceptar el parámetro tkn en la URL redirigida. Esta credencial temporal debe canjearse por un token de acceso permanente y un token de refresco, llamando a un endpoint específico (consulta el paso 2).
Paso 2: Intercambio de token
Para completar la autenticación, debes intercambiar el token temporal (tkn) recibido durante el redireccionamiento por un token de acceso y un token de actualización. Esto se realiza mediante los siguientes endpoints:
Endpoint: /authapi/v1/login_by_temp_token
Method: GET
Authentication: Authorization: Bearer <accessToken>
Body:
{
"temporalToken": "string"
}
Respuesta
{
"message": "string",
"messageType": "SUCCESS",
"errorCode": "ERROR_CODE",
"data": {
"refreshToken": "string",
"accessToken": "string",
"expiration": "<dateTime>"
}
}
Endpoint: /authapi/v1/refresh-token
Method: PUT
Authentication: Authorization: Bearer <accessToken>
Content-Type: application/json
Body:
{
"refreshToken": "string"
}
Respuesta
{
"message": "string",
"messageType": "SUCCESS",
"errorCode": "ERROR_CODE",
"data": {
"refreshToken": "string",
"accessToken": "string",
"expiration": "<dateTime>"
}
}
Endpoint: /authapi/v1/logout
Method: DELETE
Authentication: Authorization: Bearer <accessToken>
Body: None
Content-Type: application/json
Respuesta
{
"message": "string",
"messageType": "SUCCESS",
"errorCode": "ERROR_CODE",
"data": {}
}
Paso 3: Generación y emisión del certificado
Las llamadas de firma se realizan en la URL base:
https://HOSTNAME_OR_IP:PORT/raapi
Por ejemplo: https://localhost:8082/raapi/v1/csr/create o https://localhost:8082/raapi/v1/csr/finalize
Para emitir un certificado hay que llamar a dos endpoints en secuencia:
Endpoint: /raapi/v1/csr/create
Method: GET
Authentication: Authorization: Bearer <accessToken>
Content-Type: application/json
Body:
{
"dn": [
{
"attribute": "<string>",
"value": "<string>"
},
{
"attribute": "<string>",
"value": "<string>"
}
],
"hashType": "SHA384",
"keyLength": "<integer>",
"keyType": "DSA",
"provider": "<string>",
"requestCode": "<string>",
"info": {
"proident_9b": "<string>"
},
}
Devuelve un CSR y un requestCode que usarás para finalizar el proceso.
Respuesta
{
"message": "<string>",
"messageType": "IGNORE",
"errorCode": "OK",
"data": "<string>"
}
Ejemplo
Request
{
"dn": [
{
"attribute": "cn",
"value": "john doe"
},
{
"attribute": "o",
"value": "Redtrust"
},
{
"attribute": "c",
"value": "Brasil"
},
{
"attribute": "st",
"value": "PJE"
},
{
"attribute": "l",
"value": "Sao Paolo"
},
{
"attribute": "ou",
"value": "Developement"
}
],
"hashType": "SHA384",
"keyLength": "2048",
"keyType": "RSA",
"provider": "CA_BRASIL"
}
Response
{
"message": "Operation finalized successfully",
"messageType": "SUCCESS",
"errorCode": "OK",
"data": {
"requestCode": "P775W98SSW4Z1774PMZU",
"csr": "MIIDYzCCAksCAQAwADCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKpo256NtdwCAcY9tsEzQu/PYMq5lmzkyC8hHqRWKl4IQY9YdSx7Qg7r8P9GHB+CydL2IarzPSE9KXrlWUb4YyKAcEKjlsIcXyTEbTJg0WScETw25Q7lZg2K7erJYfQlLJfZ8EWkZl6ufZoxC/gL8/RMkWAhZouOHXhBy3Ut//RNHPFA1dcGjcMEIAf/rOSp2vnfD7M96ph9NZzJsovUzISogdBayY0QYHHITxtLJbGTa+QoXzPQz9toCEOktCaoJKJALHiw5/IQuEvaYXPh5sh1OGC4el5J+qprGtB4JDq6ztVFo+yK+dRvrLaCh61kblxzw/njPTUm/jXblC13wBUCAwEAAaCCARwwHAYKKwYBBAGCNw0CAzEOFgwxMC4wLjE3NzYzLjIwNwYJKwYBBAGCNxUUMSowKAIBBQwGYmV0YTAxDBFXT1JLR1JPVVBcYmV0YTAxJAwIdzN3cC5leGUwPgYJKoZIhvcNAQkOMTEwLzAdBgNVHQ4EFgQUS8EPLaw20Fc186vA+W2Hs3JgcnkwDgYDVR0PAQH/BAQDAgUgMIGCBgorBgEEAYI3DQICMXQwcgIBAR5qAE0AaQBjAHIAbwBzAG8AZgB0ACAARQBuAGgAYQBuAGMAZQBkACAAUgBTAEEAIABhAG4AZAAgAEEARQBTACAAQwByAHkAcAB0AG8AZwByAGEAcABoAGkAYwAgAFAAcgBvAHYAaQBkAGUAcgMBADANBgkqhkiG9w0BAQUFAAOCAQEAgkJ3Z3a7PCIKL46og9Wljh37xY9za5gNZ8Y+/W4ZFAkVJp0kiI1CdTrgq3XLT0lX/RZ7MOEH7U0nZKQay+wUrEnXLjETGUdr/vmifzhTNzl3Q7wrI53Qg2XAEuAho2vwIE7Hc8PKa2S9da2Z1DprbnnY09P+YlfVes5o9MEm5AKlu1kBnPAsrLSa0cSAywUsZpyTJU+5/zma//ODgTzbl99P06VHIMeJW/Pog4yX+UA420RU8z76pmwgJOs2JqfiRmx7qo5herr0V7A0qdT/pfMInpRmuJlrwAlfIowyx9uK1Tzzs5ZNKhZXaXZ626yq9p1tJcajiUiCUjbatI844w=="
},
"isValid": true
}
Endpoint: /raapi/v1/csr/finalize
Method: PUT
Authentication: Authorization: Bearer <accessToken>
Body:
{
"dataInB64": "<string>",
"provider": "<string>",
"requestCode": "<string>"
}
Response: HTTP Code Response
Content-Type: application/json
Paso 4: Renovación del certificado
Para renovar un certificado, también se utilizan dos endpoints. Ten en cuenta que la versión del endpoint de creación cambia a v2, mientras que la de finalización se mantiene en v1.
Endpoint: /raapi/v2/csr/create
Agrega el campo thumbprintToRenew al cuerpo de la petición:
{
...
"thumbprintToRenew": "<thumbprint>"
}
Ejemplo
Request
{
"dn": [
{
"attribute": "<string>",
"value": "<string>"
},
{
"attribute": "<string>",
"value": "<string>"
}
],
"hashType": "SHA384",
"keyLength": "<integer>",
"keyType": "DSA",
"provider": "<string>",
"requestCode": "<string>",
"info": {
"proident_9b": "<string>"
},
"thumbprintToRenew": "<string>"
}
Response
{
"message": "<string>",
"messageType": "IGNORE",
"errorCode": "OK",
"data": "<string>"
}
Endpoint: /raapi/v1/csr/finalize
Este paso no cambia con respecto a la emisión inicial. A continuación, se debe invocar este endpoint usando el mismo requestCode obtenido en la creación. No es necesario modificar los datos de la solicitud. El nuevo certificado reemplazará al anterior, conservando su configuración y asociaciones.
Parámetros soportados
| Parámetro | Descripción |
|---|---|
Consumer (requerido) | Debe establecerse siempre como RA_API para este servicio. |
RedirectUrl (requerido) | URL a la que se redirigirá al usuario al finalizar el proceso. Se añade una credencial temporal. Asegúrate de aplicar UrlEncode. |
Domain (opcional) | Dominio de los usuarios que usarán la API. Permite adaptar el flujo según el tipo de usuario. |
timestamp (requerido) | Marca de tiempo en formato UNIX (segundos desde epoch). |
partner (requerido) | Nombre en mayúsculas de la aplicación cliente que hace la solicitud. |
hmac (requerido) | Firma HMAC para seguridad. Consulta la sección sobre la cabecera x-hmac-signature para más información. |