Descripción general de las políticas de JWS y JWT

Esta página se aplica a Apigee y Apigee Hybrid.

Consulta la documentación de Apigee Edge.

En este tema, se proporciona información general sobre JWT (token web JSON), JWS (firma web JSON) y las políticas de Apigee JWS/JWT que pueden ser de interés para los desarrolladores del proxy de Apigee.

Introducción

JWS y JWT se usan, por lo general, para compartir reclamaciones o confirmaciones entre aplicaciones conectadas. Las políticas de JWS y JWT permiten que los proxies de la API de Apigee hagan lo siguiente:

  • Generen un JWT o JWS firmado.
  • Verifiquen un JWT o JWS firmado y reclamos dentro de JWS y JWT.
  • Decodifiquen un JWT o JWS firmado sin validar la firma.

En los últimos dos casos, la política también configura variables que permiten políticas adicionales, o servicios de backend, para inspeccionar las reclamaciones validadas y tomar decisiones basadas en esos reclamos.

Cuando usas la política de verificación de JWS/JWT, se rechazará un JWS/JWT no válida y se generará una condición de error. De manera similar, cuando se usa la política de decodificación de JWS/JWT, un JWS/JWT con formato incorrecto tendrá una condición de error.

Videos

Mira un breve video para obtener una introducción rápida a JWT. Si bien este video es específico a fin de generar un JWT, muchos de los conceptos son los mismos para JWS.

Un video corto para obtener más información sobre la estructura JWT.

Casos prácticos

Puedes usar las políticas de JWS/JWT para hacer lo siguiente:

  • Generar un nuevo JWS/JWT en los extremos del proxy de destino o del proxy de un proxy de Apigee. Por ejemplo, puedes crear un flujo de solicitud de proxy que genere un JWS/JWT y lo devuelva a un cliente. También puedes diseñar un proxy para que genere un JWS/JWT en el flujo de solicitud de destino y lo adjunte a la solicitud enviada al destino. Luego, esos reclamos estarán disponibles para permitir que los servicios de backend apliquen más procesos de seguridad.
  • Verificar y extraer reclamaciones de un JWS/JWT que se obtiene de las solicitudes de cliente entrantes, de las respuestas del servicio de destino, de las respuestas de las políticas de texto destacado del servicio o de otras fuentes. Apigee verificará la firma en un JWS/JWT, que genere un tercero o Apigee, mediante los algoritmos RSA o HMAC.
  • Decodificar un JWS/JWT. La decodificación es más útil cuando se usa junto con la política de verificación de JWS/JWT, cuando se debe conocer el valor de una reclamación (JWT) o encabezado (JWS/JWT) desde JWS/JWT antes de verificar el JWS/JWT:

Partes de un JWS/JWT

Un JWS/JWT firmado codifica la información en tres partes separadas por puntos: el encabezado, la carga útil y la firma:

header.payload.signature
  • La política de generación de JWS/JWT crea las tres partes.
  • La política de verificación de JWS/JWT examina las tres partes.
  • La política de decodificación de JWS/JWT solo examina el encabezado y la carga útil.

Un JWS también admite un formato desconectado que omite la carga útil del JWS:

header..signature

Con un JWS desconectado, la carga útil se envía por separado del JWS. Usa el elemento <DetachedContent> de la política de verificación de JWS para especificar la carga útil de JWS sin codificar ni procesar. Luego, la política de verificación de JWS verifica el JWS con el encabezado y la firma en el JWS y la carga útil especificada por el elemento <DetachedContent>.

Para obtener más información sobre los tokens y la forma en que se codifican y firman, consulta los siguientes vínculos:

Diferencias entre JWS y JWT

Puedes usar un JWT o JWS para compartir reclamaciones o confirmaciones entre aplicaciones conectadas. La principal diferencia entre los dos es la representación de la carga útil:

  • JWT
    • La carga útil siempre es un objeto JSON.
    • La carga útil siempre se adjunta al JWT
    • El encabezado typ del token siempre se configura como JWT
  • JWS
    • La carga útil se puede representar mediante cualquier formato, como un objeto JSON, una transmisión de bytes, una transmisión de octeto y otros.
    • No es necesario adjuntar la carga útil al JWS

Debido a que el formato JWT siempre usa un objeto JSON a fin de representar la carga útil, las políticas Verificar JWT y Generar JWT de Apigee que se crearon tienen compatibilidad para manejar nombres de reclamaciones registradas comunes, como aud, iss, sub y otros. Esto significa que puedes usar elementos de la política de Generar JWT para configurar estos reclamos en la carga útil y los elementos de la política de verificación de JWT a fin de verificar sus valores. Consulta la sección Nombres de reclamos registrados de la especificación JWT para obtener más información.

Además de admitir ciertos nombres de reclamos registrados, la política de generación de JWT se admite directamente si agregas reclamaciones con nombres arbitrarios al JWT. Cada reclamo es un par nombre/valor simple, en el que el valor puede ser número de tipo, booleano, string, mapa o arreglo.

Debido a que un JWS puede usar cualquier representación de datos para la carga útil, no puedes agregar reclamaciones a ella. La política Generar JWS admite la adición de reclamaciones con nombres arbitrarios al encabezado de JWS. Además, las políticas JWS admiten una carga útil desconectada, en la que JWS omite la carga útil. Una carga útil desconectada te permite enviar el JWS y la carga útil por separado, y es necesario para diversos estándares de seguridad.

Acerca de los algoritmos de firma

Las políticas JWS/JWT y de verificación de JWS/JWT admiten algoritmos RSA, RSASSA-PSS, ECDSA y HMAC, mediante sumas de verificación SHA2 de intensidad de bit de 256, 384 o 512. La política de decodificación de JWS/JWT funciona independientemente del algoritmo que se usó para firmar el JWS/JWT.

Algoritmo HMAC

El algoritmo HMAC depende de un secreto compartido, conocido como la clave secreta, para crear la firma (también conocida como la firma de JWS/JWT) y verificarla.

La longitud mínima de la clave secreta depende de la intensidad de bits del algoritmo:

  • HS256: Longitud mínima de clave de 32 bytes
  • HS386: Longitud mínima de clave de 48 bytes
  • HS512: Longitud mínima de clave de 64 bytes

algoritmo de RSA

El algoritmo de RSA usa un par de claves pública/privada para la firma criptográfica. Con las firmas de RSA, la parte de firma usa una clave privada RSA para firmar el JWS/JWT y la parte verificada usa la clave pública RSA correspondiente a fin de verificar la firma en el JWS/JWT. No hay requisitos de tamaño para las claves.

Algoritmo RSASSA-PSS

El algoritmo RSASSA-PSS es una actualización del algoritmo de RSA. Al igual que RSS, RSASSA-PSS usa un par de claves pública/privada RSA para la firma criptográfica. El formato de la clave es el mismo que para el de RSS. La parte que firma usa una clave privada para firmar el JWS/JWT y la parte verificadora usa la clave pública coincidente a fin de verificar la firma en el JWS/JWT. No hay requisitos de tamaño para las claves.

Algoritmo ECDSA

El algoritmo de la curva digital de curva elíptica (ECDSA) es un algoritmo de criptografía de curva elíptica con una curva P-256, P-384 y P-521. Cuando usas algoritmos de ECDSA, el algoritmo determina el tipo de clave pública y privada, debes especificar lo siguiente:

Algoritmo Curva Requisito de la clave
ES256 P-256 Una clave generada a partir de la curva P-256 (también conocida como secp256r1 o prime256v1)
ES384 P-384 Una clave generada a partir de la curva P-384 (también conocida como secp384r1)
ES512 P-521 Una clave generada a partir de la curva P-521 (también conocida como secp521r1)

Algoritmos de encriptación de claves

Las políticas de JWS/JWT admiten todos los algoritmos de encriptación de claves compatibles con OpenSSL.

Usa un conjunto de claves web JSON (JWKS) para verificar un JWS/JWT

Cuando verificas un JWS/JWT firmado, debes proporcionar la clave pública asociada con la clave privada que se usa para firmar el token. Tienes dos opciones para proporcionar la clave pública a las políticas de verificación de JWS/JWT:

  • Usa el valor real de clave pública (por lo general, se proporciona en una variable de flujo), o
  • usa una clave pública unida a un JWKS.

Acerca de JWKS

Un JWKS es una estructura JSON que representa un conjunto de claves web JSON (JWK). Un JWK es una estructura de datos JSON que representa una clave criptográfica. JWK y JWKS se describen en RFC7517. Consulta ejemplos de JKWS en Apéndice A. Ejemplo de conjuntos de claves web JSON

Estructura de JWKS

RFC7517 describe los elementos clave de JWKS para cada tipo de clave, como RSA o EC. Por ejemplo, según el tipo de clave, estos parámetros pueden incluir las siguientes claves:

  • kty: Es el tipo de clave, como RSA o EC.
  • kid (ID de clave): Puede ser cualquier valor arbitrario (sin duplicados dentro de un conjunto de claves). Si el JWT entrante ingresa un ID de clave presente en el conjunto de JWKS, la política usará la clave pública correcta para verificar la firma de JWS/JWT.

A continuación, se presentan ejemplos de elementos opcionales y sus valores:

  • alg: Es el algoritmo clave. Debe coincidir con el algoritmo de firma del JWS/JWT.
  • use: Si está presente, debe ser sig.

Los siguientes JWKS incluyen los elementos y valores necesarios, y serían válidos en Apigee (desde https://www.googleapis.com/oauth2/v3/certs):

{
   "keys":[
      {
         "kty":"RSA",
         "alg":"RS256",
         "use":"sig",
         "kid":"ca04df587b5a7cead80abee9ea8dcf7586a78e01",
         "n":"iXn-WmrwLLBa-QDiToBozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt7-V7KDjCq0_Nkd-X9rMRV5LKgCa0_F8YgI30QS3bUm9orFryrdOc65PUIVFVxIwMZuGDY1hj6HEJVWIr0CZdcgNIll06BasclckkUK4O-Eh7MaQrqb646ghFlG3zlgk9b2duHbDOq3s39ICPinRQWC6NqTYfqg7E8GN_NLY9srUCc_MswuUfMJ2cKT6edrhLuIwIj_74YGkpOwilr2VswKsvJ7dcoiJxheKYvKDKtZFkbKrWETTJSGX2Xeh0DFB0lqbKLVvqkM2lFU2Qx1OgtTnrw",
         "e":"AQAB"
      },
      {
          "kty":"EC",
          "alg":"ES256",
          "use":"enc",
          "kid":"k05TUSt7-V7KDjCq0_N"
          "crv":"P-256",
          "x":"Xej56MungXuFZwmk_xccvsMpCtXmqhvEEMCmHyAmKF0",
          "y":"Bozpu4Y4ThKdwORWFXQa9I75pKOvPUjUjE2Bk05TUSt",
      }
   ]
}

Diseña tu proxy para usar JWKS

Cuando se obtiene un JWS/JWT a partir de una entidad emisora, a menudo, el emisor inserta un ID de clave (o kid) en el encabezado JWS/JWT. La clave le indica al destinatario del JWS/JWT cómo encontrar la clave pública o secreta necesaria para verificar la firma en el JWS/JWT firmado.

A modo de ejemplo, supongamos que una entidad emisora firma un JWT con una clave privada. El “ID de clave” identifica la clave pública coincidente que se debe usar para verificar el JWT. Por lo general, la lista de claves públicas está disponible en algún extremo conocido, por ejemplo: https://www.googleapis.com/oauth2/v3/certs.

Esta es la secuencia básica que Apigee (o cualquier plataforma que funciona con JWKS) debe realizar para trabajar con un JWS/JWT que tiene una JWKS:

  1. Examine el encabezado JWS/JWT para encontrar el ID de clave (kid).
  2. Examina el encabezado JWS/JWT para encontrar el algoritmo de firma (alg), como RS256.
  3. Recupera la lista de claves y el ID de JWKS del extremo conocido para una entidad emisora.
  4. Extrae la clave pública de la lista de claves con el ID de clave indicado en el encabezado JWS/JWT y con el algoritmo de coincidencia, si la clave JWKS especifica el algoritmo.
  5. Usa esa clave pública para verificar la firma en el JWS/JWT.

Como desarrollador de un proxy de API de Apigee, debe hacer lo siguiente para realizar la verificación JWS/JWT:

  1. Recupera una lista de claves y los ID del extremo conocido de una entidad emisora determinada. Puedes usar una política Service Callout para este paso.
  2. En la política de verificación de JWS/JWT, especifica la ubicación de JWS/JWT en el elemento <Source> y la carga útil JWKS en el elemento <PublicKey/JWKS>. Por ejemplo, para la política VerifyJWT:
    <VerifyJWT name="JWT-Verify-RS256">
        <Algorithm>RS256</Algorithm>
        <Source>json.jwt</Source>
        <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables>
        <PublicKey>
            <JWKS ref="public.jwks"/>
        </PublicKey>
        <Subject>apigee-seattle-hatrack-montage</Subject>
        <Issuer>urn://apigee-edge-JWT-policy-test</Issuer>
        <Audience>urn://c60511c0-12a2-473c-80fd-42528eb65a6a</Audience>
        <AdditionalClaims>
            <Claim name="show">And now for something completely different.</Claim>
        </AdditionalClaims>
    </VerifyJWT>
    

La política Verificar JWT realiza todo lo demás:

  • Si una clave con un ID de clave que coincide con el ID de clave (kid) que se indicó en el JWT no se encuentra en los JWKS, la política Verificar de JWT arroja un error y no valida el JWT.
  • Si el JWT entrante no tiene un ID de clave (kid) en el encabezado, no es posible asignar keyid-to-verification-key.

Como diseñador de proxy, eres responsable de determinar la clave que se usará. En algunos casos, se puede usar una clave fija y codificada.