Keycloak

Para utilizar Keycloak con NetHSM y así almacenar de forma segura las claves privadas en NetHSM, al tiempo que se permite a Keycloak firmar tokens de acceso y descifrar JWE, es necesario instalar y configurar este proveedor de claves de la siguiente manera:

Declaración sobre la IA

Este proveedor se ha desarrollado y revisado con una importante ayuda de la inteligencia artificial.

Prepare the NetHSM

Prepara el NetHSM de la siguiente manera. Consulta la sección administration para obtener instrucciones detalladas.

  • Si NetHSM utiliza un certificado autofirmado, anota su huella digital:

    echo | openssl s_client -connect $NETHSM_HOST 2>/dev/null \
      | openssl x509 -fingerprint -sha256 -noout
    
  • Crea un usuario de tipo «Operador» dedicado a Keycloak.

  • La extensión de Keycloak detecta las claves de, pero no las crea. Crea las claves deseadas manualmente:

    • El ID de clave debe comenzar con el prefijo que reclamará el dominio. Elige un esquema de nomenclatura adecuado, como kc-<realm>-<purpose>-<year> (por ejemplo, kc-staff-sig-rs256-2026, kc-partners-sig-es256-2026, kc-customers-enc-oaep-2026). El ID se convierte en el kid que publica Keycloak. La futura rotación de claves se lleva a cabo añadiendo nuevos ID, por lo que recomendamos utilizar el año como parte del ID de clave.

    • Los mecanismos determinan para qué algoritmos JOSE puede utilizarse la clave:

      NetHSM key type and mechanism

      JOSE algorithms served

      RSA + RSA_Signature_PKCS1

      RS256, RS384, RS512: compatible con cualquier algoritmo hash, por lo que una sola clave sirve para los tres

      RSA + RSA_Signature_PSS_SHA256 / _SHA384 / _SHA512

      PS256 / PS384 / PS512: solo el algoritmo, no los nombres de los mecanismos

      EC_P256 / EC_P384 / EC_P521 + ECDSA_Signature

      ES256 / ES384 / ES512: la curva determina el algoritmo

      Curve25519 + EdDSA_Signature

      EdDSA

      RSA + RSA_Decryption_OAEP_SHA1 / _SHA256

      RSA-OAEP / RSA-OAEP-256, para descifrar JWE entrantes

Instalación

Descarga el archivo JAR del proveedor NetHSM de Keycloak ` <https://github.com/Nitrokey/nethsm-keycloak/releases>` __, guárdalo en la carpeta de proveedores de Keycloak, por ejemplo: /opt/keycloak/providers/

Recompilar el registro de proveedores: /opt/keycloak/bin/kc.sh build

Configuración

Los ajustes pueden especificarse en conf/keycloak.conf o como variables de entorno. Ambas formas corresponden a los mismos ajustes; las variables de entorno tienen prioridad, por lo que los valores que no sean confidenciales pueden almacenarse en el archivo y solo se insertará la frase de contraseña en tiempo de ejecución.

Utilizando conf/keycloak.conf

spi-keys--nethsm--url=https://nethsm.internal:8443/api/v1
spi-keys--nethsm--username=keycloak
spi-keys--nethsm--passphrase=<passphrase>
spi-keys--nethsm--tls-fingerprints=aabbcc...

Using environment variables

Se recomienda para implementaciones en contenedores, ya que la frase de contraseña se puede proporcionar desde un secreto de Docker o Kubernetes en lugar de escribirse en un archivo.

KC_SPI_KEYS__NETHSM__URL=https://nethsm.internal:8443/api/v1
KC_SPI_KEYS__NETHSM__USERNAME=keycloak
KC_SPI_KEYS__NETHSM__PASSPHRASE="<passphrase>"
KC_SPI_KEYS__NETHSM__TLS_FINGERPRINTS=aabbcc...

Nota

El nombre de la variable de entorno se deriva automáticamente de la clave de configuración: se le antepone KC_, se convierte a mayúsculas y se sustituye cada - por _. Los guiones bajos dobles se derivan de la estructura de la clave, spi-<spi-name>--<provider-id>--<option>, que para esta extensión es SPI keys, proveedor nethsm y el nombre de la opción.

See also all available configuration options.

Restart Keycloak

El perfil de conexión solo se lee al inicializar la fábrica de proveedores. Reinicia Keycloak.

Confirm the server configuration

Comprueba el registro de inicio antes de configurar cualquier ámbito. De este modo, se distingue entre un problema de conexión o de credenciales y un problema de configuración del ámbito.

En caso de éxito:

NetHSM key provider ready: 1 instance(s), user 'keycloak',
discovery cache PT5M, on-unavailable fail

Otherwise:

Log message

Cause

No aparece ningún mensaje, o aparece una línea de depuración que indica que el proveedor está inactivo

url is not set

NetHSM is not reachable or not Operational at startup

Dirección incorrecta, bloqueado por un cortafuegos, discrepancia en el PIN del certificado, o bien el NetHSM está bloqueado o sin configurar

NetHSM rejected the configured credential with HTTP 401

Wrong username or passphrase

Añadir el proveedor a un ámbito

En la consola de administración, ve a Configuración del reino → Claves → Proveedores, selecciona Añadir proveedor y selecciona nethsm.

Field

Significado

Key use

sig para firmar tokens, enc para descifrar JWE entrantes

Key ID prefix

Cada clave NetHSM cuyo ID comience por esta cadena es publicada por este dominio.

Algorithm

El algoritmo bajo el que se publican estas claves

Priority

Consulta Establece la prioridad por encima de 100

Enabled / Active

Ambas deben estar activadas para que una clave pueda firmar

Un componente publica un algoritmo, al igual que los proveedores de claves integrados de Keycloak. Por lo tanto, un reino que necesite tanto RS256 como ES256 cuenta con dos componentes. Las claves bajo el prefijo que no puedan utilizar el algoritmo elegido se omiten, por lo que un prefijo puede corresponder sin problemas a un conjunto mixto de claves.

Prudencia

No apuntes dos componentes a la misma clave con algoritmos diferentes. Ambos publicarían una entrada JWKS bajo el mismo kid.

Establece la prioridad por encima de 100

Importante

Un reino recién creado contiene cuatro proveedores de claves generados: rsa-generated, rsa-enc-generated, hmac-generated y aes-generated, todos ellos con la prioridad 100. El componente NetHSM debe tener una prioridad más alta; de lo contrario, Keycloak seguirá firmando con una clave de software generada y la configuración parecerá funcionar.

Un valor de 200 para NetHSM es un valor predeterminado razonable.

Selecciona el algoritmo para el reino

Establece Realm Settings → Tokens → Default Signature Algorithm en el algoritmo configurado en el componente. Si el realm solicita un algoritmo que el componente no publica, Keycloak recurre a una clave generada sin notificar ningún error.

Verificar

List the published keys:

curl -s https://<keycloak-host>/realms/<realm>/protocol/openid-connect/certs

Los valores de « ` » kid` deben ser los ID de clave de NetHSM.

La comprobación definitiva es un token emitido. Solicita uno y descodifica su encabezado:

curl -s \
  -d "client_id=<client>" \
  -d "client_secret=<secret>" \
  -d "grant_type=client_credentials" \
  https://$NETHSM_HOST/realms/<realm>/protocol/openid-connect/token \
| python3 -c 'import sys, json, base64
header = json.load(sys.stdin)["access_token"].split(".")[0]
print(json.loads(base64.urlsafe_b64decode(header + "==")))'

Si kid es el ID de la clave de NetHSM, la firma se generó dentro del HSM. También puedes consultar el registro de NetHSM al mismo tiempo, donde debería aparecer la llamada correspondiente.

Plan para el caso de que NetHSM no esté disponible

Si no es posible conectarse a NetHSM y no hay metadatos de claves almacenados en caché, el dominio no dispone de claves válidas y la emisión de tokens falla, en lugar de recurrir a una clave de software generada.

Advertencia

Si el algoritmo de firma predeterminado de un dominio se gestiona mediante claves NetHSM y no se puede acceder a NetHSM, tampoco se podrán emitir tokens administrativos para ese dominio. En ese caso, la API de administración no estará disponible para solucionar el problema.

La recuperación se realiza a través de la configuración del servidor, en lugar de la consola de administración: establece spi-keys--nethsm--on-unavailable=degrade y reinicia, o desactiva el componente.

Por este motivo, configura primero un ámbito de prueba y deja que el ámbito master utilice las claves generadas por el propio Keycloak, para que se pueda seguir accediendo a la consola de administración.

Further Details

You find further details here.