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

Estás consultando la documentación de Apigee Edge.
Consulta la documentación de Apigee X.
Información

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/JWT habilitan a los proxies de la API de Edge para 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 de uso

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

  • Genera un JWS/JWT nuevo en los lados del proxy o del extremo de destino de un proxy perimetral. 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. Edge verificará la firma en un JWS/JWT, ya sea que haya sido generado por un tercero o por el mismo Edge, con 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 detached 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 cómo se codifican y se firman, consulta el siguiente artículo:

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 para representar la carga útil, las políticas de generación perimetral de JWT y verificación de JWT tienen compatibilidad integrada 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),
  • 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 (el 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: Algoritmo clave. Debe coincidir con el algoritmo de firma en JWS/JWT.
  • use: Si está presente, debe ser Siri.

El siguiente JWKS incluye los elementos y valores obligatorios, y sería válido en Edge (de 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 Edge (o cualquier plataforma que funcione con JWKS) debe realizar para trabajar con un JWS/JWT que tenga un 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 anotado en el encabezado JWS/JWT y con el algoritmo coincidente, si la clave JWKS especifica el algoritmo.
  5. Usa esa clave pública para verificar la firma en el JWS/JWT.

Como desarrollador de proxy de la API de Edge, debes hacer lo siguiente para realizar la verificación de 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, usa lo siguiente:
    <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.