Visão geral das políticas JWS e JWT

Esta página se aplica à Apigee e à Apigee híbrida.

Confira a documentação da Apigee Edge.

Neste tópico, fornecemos informações gerais sobre JWT (JSON Web Token) e JWS (JSON Web Signature) e as políticas JWS/JWT da Apigee que podem ser de interesse para desenvolvedores de proxy da Apigee.

Introdução

JWS e JWT são comumente usados para compartilhar declarações ou asserções entre aplicativos conectados. As políticas de JWS/JWT permitem que os proxies da API Apigee:

  • Gerem um JWT ou JWS assinado.
  • Verifiquem um JWT assinado ou JWS e declarações no JWS/JWT.
  • Decodifiquem um JWT ou JWS assinado sem validar a assinatura.

Nos últimos dois casos, a política também define variáveis que permitem que políticas extras ou os próprios serviços de back-end inspecionem as declarações validadas e tomem decisões com base nessas declarações.

Ao usar a política Verify JWS/JWT, um JWS/JWT inválido será recusado e resultará em uma condição de erro. Da mesma forma, ao usar a política Decode JWS/JWT, um JWS/JWT malformado resultará em uma condição de erro.

Vídeos

Assista a um vídeo curto para uma introdução rápida ao JWT. Este vídeo é específico para gerar um JWT, mas muitos dos conceitos são os mesmos para JWS.

Um vídeo curto para saber mais sobre a estrutura do JWT.

Casos de uso

As políticas JWS/JWT podem ser usadas para:

  • Gerar um novo JWS/JWT no lado do proxy ou do endpoint de destino de um proxy da Apigee. Por exemplo, é possível criar um fluxo de solicitação de proxy que gere um JWS/JWT e o retorne a um cliente. Ou é possível projetar um proxy para que ele gere um JWS/JWT no fluxo de solicitação de destino e o anexe à solicitação enviada ao destino. Essas declarações estarão disponíveis para permitir que os serviços de back-end apliquem mais processamento de segurança.
  • Verifique e extraia declarações de um JWS/JWT obtido de solicitações de cliente de entrada, de respostas de serviço de destino, de respostas de política de chamada de serviço ou de outras fontes. A Apigee verificará a assinatura em um JWS/JWT, se o JWS/JWT foi gerado por terceiros ou pela Apigee em si usando os algoritmos RSA ou HMAC.
  • Decodificar um JWS/JWT. A decodificação é mais útil quando usada em conjunto com a política Verify JWS/JWT, quando o valor de uma declaração (JWT) ou cabeçalho (JWS/JWT) do JWS/JWT precisa ser conhecido antes de verificar o JWS/JWT.

Partes de um JWS/JWT

Um JWS/JWT assinado codifica as informações em três partes separadas por pontos: cabeçalho, o payload e a assinatura:

header.payload.signature
  • A política Generate JWS/JWT cria as três partes.
  • A política Verify JWS/JWT examina as três partes.
  • A política Decode JWS/JWT examina apenas o cabeçalho e o payload.

Um JWS também aceita um formato desanexado que omite o payload do JWS:

header..signature

Com um JWS desanexado, o payload é enviado separadamente do JWS. Use o elemento <DetachedContent> da política Verify JWS para especificar o payload bruto não codificado do JWS. Em seguida, a política Verify JWS verifica o JWS usando o cabeçalho e a assinatura no JWS e o payload especificado pelo elemento <DetachedContent>.

Para saber mais sobre tokens e como eles são codificados e assinados, consulte:

Diferenças entre JWS e JWT

Use um JWT ou JWS para compartilhar declarações ou afirmações entre aplicativos conectados. A principal diferença entre os dois é a representação do payload:

  • JWT
    • O payload é sempre um objeto JSON
    • O payload é sempre anexado ao JWT
    • O cabeçalho typ do token sempre é definido como JWT
  • JWS
    • O payload pode ser representado por qualquer formato, como um objeto JSON, fluxo de bytes, fluxo de octetos e outros
    • O payload não precisa ser anexado ao JWS

Como o formato JWT sempre usa um objeto JSON para representar o payload, as políticas Generate JWT e Verify JWT da Apigee foram criadas para processar nomes registrados comuns de declaração, como aud, iss, sub e outros. Isso significa que é possível usar elementos da política Generate JWT para definir essas declarações no payload e elementos da política Verify JWT para verificar os valores deles. Consulte a seção Nomes de declarações registrados da especificação do JWT para saber mais.

Além de aceitar determinados nomes de declaração registrados, a política Generate JWT é diretamente compatível com a adição de declarações com nomes arbitrários para o JWT. Cada declaração é um par de nome/valor simples, em que o valor pode ser do tipo número, booleano, string, mapa ou matriz.

Como um JWS pode usar qualquer representação de dados para o payload, não é possível adicionar declarações ao payload. A política Generate JWS permite adicionar declarações com nomes arbitrários ao cabeçalho do JWS. Além disso, as políticas JWS são compatíveis com um payload desanexado, em que o JWS omite o payload. Um payload desanexado permite o envio do JWS e do payload separadamente e é exigido por vários padrões de segurança.

Sobre algoritmos de assinatura

As políticas de verificação e geração de JWS/JWT são compatíveis com algoritmos RSA, RSASSA-PSS, ECDSA e HMAC, usando somas de verificação SHA2 de força de bits de 256, 384 ou 512. A política de decodificação de JWS/JWT funciona independentemente do algoritmo usado para assinar o JWS/JWT.

Algoritmo HMAC

O algoritmo HMAC depende de um secret compartilhado, conhecido como chave secreta, para criar a assinatura (também chamado de "assinar o JWS/JWT") e para verificar a assinatura.

O comprimento mínimo da chave secreta depende da força do bit do algoritmo:

  • HS256: comprimento mínimo de chave de 32 bytes
  • HS386: comprimento mínimo de 48 bytes
  • HS512: tamanho mínimo da chave de 64 bytes

Algoritmo RSA

O algoritmo RSA usa um par de chaves pública/privada para a assinatura criptográfica. Com assinaturas RSA, a parte assinante usa uma chave privada RSA para assinar o JWS/JWT. A parte verificadora usa a chave pública RSA correspondente para verificar a assinatura no JWS/JWT. As chaves não têm requisitos de tamanho.

Algoritmo RSASSA-PSS

O algoritmo RSASSA-PSS é uma atualização do algoritmo RSA. Assim como o RSS, o RSASSA-PSS usa um par de chaves públicas/privadas RSA para a assinatura criptográfica. O formato da chave é o mesmo que para RSS. A parte assinante usa uma chave privada para assinar o JWS/JWT e a parte verificadora usa a chave pública correspondente para verificar a assinatura no JWS/JWT. Não há requisitos de tamanho para as chaves.

Algoritmo ECDSA

O algoritmo de assinatura digital de curva elíptica (ECDSA, na sigla em inglês) é um algoritmo de criptografia de curva elíptica com uma curva P-256, P-384 e P-521. Quando você usa algoritmos de ECDSA, o algoritmo determina o tipo de chave pública e privada que você precisa especificar:

Algoritmo Curva Requisito de chave
ES256 P-256 Uma chave gerada da curva P-256 (também conhecida como secp256r1 ou prime256v1)
ES384 P-384 Uma chave gerada da curva P-384 (também conhecida como secp384r1)
ES512 P-521 Uma chave gerada da curva P-521 (também conhecida como secp521r1)

Algoritmos de criptografia de chaves

As políticas de JWS/JWT aceitam todos os algoritmos de criptografia de chaves compatíveis com o OpenSSL.

Como usar um conjunto de chaves web JSON (JWKS, na sigla em inglês) para verificar um JWS/JWT

Ao verificar um JWS/JWT assinado, você precisa fornecer a chave pública associada à chave privada usada para assinar o token. Você tem duas opções para fornecer a chave pública para as políticas de verificação de JWS/JWT:

  • Use o valor da chave pública real (normalmente fornecido em uma variável de fluxo) ou
  • Use uma chave pública encapsulada em um JWKS.

Sobre JWKS

Um JWKS é uma estrutura JSON que representa um conjunto de chaves web JSON (JWKs, na sigla em inglês). Uma JWK é uma estrutura de dados JSON que representa uma chave criptográfica. JWK e JWKS são descritos em RFC7517 (em inglês). Veja exemplos de JKWS no Apêndice A. Exemplo de conjuntos de chaves web JSON

Estrutura de JWKS

RFC7517 descreve os elementos de cada tipo de chave JWKS, como RSA ou EC. Por exemplo, dependendo do tipo de chave, esses parâmetros podem incluir:

  • kty: o tipo de chave, como RSA ou EC.
  • kid (o ID da chave): pode ser qualquer valor arbitrário (sem cópias de um conjunto de chaves). Se o JWT de entrada tiver um ID de chave que está presente no conjunto de JWKS, a política usará a chave pública correta para verificar a assinatura JWS/JWT.

Veja a seguir exemplos de elementos opcionais e os valores deles:

  • alg: o algoritmo de chave. Ele precisa corresponder ao algoritmo de assinatura no JWS/JWT.
  • use: se estiver presente, precisa ser sig.

O JWKS a seguir inclui os elementos e valores necessários e seria válido na Apigee (em 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",
      }
   ]
}

Como projetar seu proxy para usar JWKS

Quando um JWS/JWT é recebido de um emissor, muitas vezes o emissor insere um ID de chave (ou filho) no cabeçalho JWS/JWT. A chave informa ao destinatário do JWS/JWT como encontrar a chave pública ou secreta necessária para verificar a assinatura no JWS/JWT assinado.

Por exemplo, suponha que um emissor assine um JWT com uma chave privada. O "ID da chave" identifica a chave pública correspondente a ser usada para verificar o JWT. A lista de chaves públicas geralmente está disponível em algum endpoint conhecido, por exemplo: https://www.googleapis.com/oauth2/v3/certs.

Esta é a sequência básica que a Apigee (ou qualquer plataforma que funcione com o JWKS) precisa executar para trabalhar com um JWS/JWT com JWKS:

  1. Examine o cabeçalho JWS/JWT para encontrar o ID da chave (filho).
  2. Examine o cabeçalho JWS/JWT para encontrar o algoritmo de assinatura (alg), como RS256.
  3. Recupere a lista de chaves e IDs de JWKS do endpoint conhecido para um determinado emissor.
  4. Extraia a chave pública da lista de chaves com o ID da chave anotado no cabeçalho JWS/JWT e com o algoritmo correspondente se a chave JWKS especificar o algoritmo.
  5. Use essa chave pública para verificar a assinatura no JWS/JWT.

Como desenvolvedor de proxy da API Apigee, você precisa fazer o seguinte para realizar a verificação de JWS/JWT:

  1. Recupere a lista de chaves e IDs do endpoint conhecido para um determinado emissor. É possível usar uma política de chamada de serviço nesta etapa.
  2. Na política Verify JWS/JWT, especifique o local do JWS/JWT no elemento <Source> e o payload de JWKS no elemento <PublicKey/JWKS>. Por exemplo, para a 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>
    

A política Verify JWT faz todo o restante:

  • Se uma chave com um ID de chave que corresponde ao ID de chave (filho) declarado no JWT não foi encontrada no JWKS, a política Verify JWT gera um erro e não valida o JWT.
  • Se o JWT de entrada não contiver um ID de chave (filho) no cabeçalho, esse mapeamento de ID de chave para chave de verificação não será possível.

Como designer de proxy, você é responsável por determinar a chave a ser usada. Em alguns casos, pode ser uma chave fixa e codificada.