Panoramica dei criteri JWS e JWT

Stai visualizzando la documentazione di Apigee Edge.
Consulta la documentazione di Apigee X.
info

Questo argomento fornisce informazioni generali su JWT (JSON Web Token) e JWS (JSON Web Signature) e sui criteri JWS/JWT di Apigee che potrebbero interessare gli sviluppatori di proxy Apigee.

Introduzione

Sia JWS che JWT sono di uso comune per condividere attestazioni tra applicazioni connesse. I criteri JWS/JWT consentono ai proxy API Edge di:

  • Generare un JWT o JWS firmato.
  • Verificare un JWT o JWS firmato e le attestazioni all'interno del JWS/JWT.
  • Decodificare un JWT o JWS firmato senza convalidare la firma.

Negli ultimi due casi, il criterio imposta anche le variabili che consentono ad altri criteri o ai servizi di backend stessi di esaminare le attestazioni convalidate e di prendere decisioni in base a queste attestazioni.

Quando si utilizza il criterio Verify JWS/JWT, un JWS/JWT non valido viene rifiutato e genera una condizione di errore. Allo stesso modo, quando si utilizza il criterio Decode JWS/JWT, un JWS/JWT non valido genera una condizione di errore.

Video

Guarda un breve video per una rapida introduzione a JWT. Sebbene questo video sia specifico per la generazione di un JWT, molti dei concetti sono gli stessi per JWS.

Guarda un breve video per scoprire di più sulla struttura JWT.

Casi d'uso

Puoi utilizzare i criteri JWS/JWT per:

  • Generare un nuovo JWS/JWT sul proxy o sugli endpoint di destinazione di un proxy Edge. Ad esempio, puoi creare un flusso di richieste proxy che genera un JWS/JWT e lo restituisce a un client. In alternativa, puoi progettare un proxy in modo che generi un JWS/JWT nel flusso di richieste di destinazione e lo alleghi alla richiesta inviata alla destinazione. Queste attestazioni sarebbero quindi disponibili per consentire ai servizi di backend di applicare un'ulteriore elaborazione di sicurezza.
  • Verificare ed estrarre le attestazioni da un JWS/JWT ottenuto da richieste client in entrata, da risposte del servizio di destinazione , da risposte dei criteri Service Callout o da altre origini. Edge verificherà la firma su un JWS/JWT, sia che sia stato generato da una terza parte sia da Edge stesso, utilizzando gli algoritmi RSA o HMAC.
  • Decodificare un JWS/JWT. La decodifica è più utile se utilizzata in combinazione con il criterio Verify JWS/JWT, quando il valore di un'attestazione (JWT) o di un'intestazione (JWS/JWT) all'interno del JWS/JWT deve essere noto prima di verificare il JWS/JWT.

Componenti di un JWS/JWT

Un JWS/JWT firmato codifica le informazioni in tre parti separate da punti: l'intestazione, il payload e la firma:

header.payload.signature
  • Il criterio Generate JWS/JWT crea tutte e tre le parti.
  • Il criterio Verify JWS/JWT esamina tutte e tre le parti.
  • Il criterio Decode JWS/JWT esamina solo l'intestazione e il payload.

Un JWS supporta anche un formato separato che omette il payload dal JWS:

header..signature

Con un JWS separato, il payload viene inviato separatamente dal JWS. Utilizza l'elemento <DetachedContent> del criterio Verify JWS per specificare il payload JWS non codificato. Il criterio Verify JWS verifica quindi il JWS utilizzando l'intestazione e la firma nel JWS e il payload specificato dall'elemento <DetachedContent>.

Per scoprire di più sui token e su come vengono codificati e firmati, consulta:

Differenze tra JWS e JWT

Puoi utilizzare un JWT o un JWS per condividere attestazioni tra applicazioni connesse. La principale differenza tra i due è la rappresentazione del payload:

  • JWT
    • Il payload è sempre un oggetto JSON
    • Il payload è sempre allegato al JWT
    • L'intestazione typ del token è sempre impostata su JWT
  • JWS
    • Il payload può essere rappresentato da qualsiasi formato, ad esempio un oggetto JSON, un flusso di byte, un flusso di ottetti e altri
    • Il payload non deve essere allegato al JWS

Poiché il formato JWT utilizza sempre un oggetto JSON per rappresentare il payload, i criteri Edge Generate JWT e Verify JWT hanno il supporto integrato per gestire i nomi delle attestazioni registrate comuni, come aud, iss, sub e altri. Ciò significa che puoi utilizzare gli elementi del criterio Generate JWT per impostare queste attestazioni nel payload e gli elementi del criterio Verify JWT per verificarne i valori. Per ulteriori informazioni, consulta la sezione Nomi delle attestazioni registrate della specifica JWT.

Oltre a supportare determinati nomi di attestazioni registrate, il criterio Generate JWT supporta direttamente l'aggiunta di attestazioni con nomi arbitrari al JWT. Ogni attestazione è una semplice coppia nome/valore, in cui il valore può essere di tipo numero, booleano, stringa, mappa o array.

Poiché un JWS può utilizzare qualsiasi rappresentazione dei dati per il payload, non puoi aggiungere attestazioni al payload. Il criterio Generate JWS supporta l'aggiunta di attestazioni con nomi arbitrari all'intestazione del JWS. Inoltre, i criteri JWS supportano un payload separato, in cui il JWS omette il payload. Un payload separato consente di inviare separatamente il JWS e il payload ed è richiesto da diversi standard di sicurezza.

Prevenire l'iniezione di modelli quando si utilizzano JWS e JWT

Per impedire la divulgazione non autorizzata dei dati, segui queste linee guida quando utilizzi i criteri GenerateJWT o GenerateJWS:

  • Evita i riferimenti diretti all'input dell'utente: non utilizzare mai input non attendibili (ad esempio request.queryparam.* o request.header.*) direttamente in un ref attributo che supporta i modelli.
  • Sanifica l'input: se devi utilizzare dati esterni in un'attestazione JWT/JWS, utilizza prima un criterio AssignMessage per rimuovere eventuali parentesi graffe ({ }) o altri caratteri di modello dall'input prima di farvi riferimento.
  • Utilizza attestazioni esplicite per le stringhe: per le semplici attestazioni di stringhe, evita type="map". L'utilizzo di type="string" predefinito impedisce la creazione implicita di modelli del valore a cui viene fatto riferimento.
  • Tieni presente l'incoerenza comportamentale tra i criteri di verifica e di generazione: i criteri di generazione JWS e JWT si comportano in modo diverso rispetto ai criteri di verifica per quanto riguarda i modelli.

Informazioni sugli algoritmi di firma

I criteri di verifica JWS/JWT e di generazione JWS/JWT supportano gli algoritmi RSA, RSASSA-PSS, ECDSA e HMAC, utilizzando i checksum SHA2 con una forza di bit di 256, 384 o 512. Il criterio Decode JWS/JWT funziona indipendentemente dall' algoritmo utilizzato per firmare il JWS/JWT.

Algoritmo HMAC

L'algoritmo HMAC si basa su un secret condiviso, noto come chiave segreta, per creare la firma (nota anche come firma del JWS/JWT) e per verificarla.

La lunghezza minima della chiave segreta dipende dalla forza di bit dell'algoritmo:

  • HS256: lunghezza minima della chiave di 32 byte
  • HS386: lunghezza minima della chiave di 48 byte
  • HS512: lunghezza minima della chiave di 64 byte

Algoritmo RSA

L'algoritmo RSA utilizza una coppia di chiavi pubblica/privata per la firma crittografica. Con le firme RSA , la parte che firma utilizza una chiave privata RSA per firmare il JWS/JWT e la parte che verifica utilizza la chiave pubblica RSA corrispondente per verificare la firma sul JWS/JWT. Non esistono requisiti di dimensione per le chiavi.

Algoritmo RSASSA-PSS

L'algoritmo RSASSA-PSS è un aggiornamento dell'algoritmo RSA. Come RSS, RSASSA-PSS utilizza una coppia di chiavi pubblica/privata RSA per la firma crittografica. Il formato della chiave è lo stesso di RSS. La parte che firma utilizza una chiave privata per firmare il JWS/JWT e la parte che verifica utilizza la chiave pubblica corrispondente per verificare la firma sul JWS/JWT. Non esistono requisiti di dimensione per le chiavi.

Algoritmo ECDSA

L'algoritmo Elliptic Curve Digital Signature Algorithm (ECDSA) è un algoritmo di crittografia a curva ellittica algoritmo con una curva P-256, P-384 e P-521. Quando utilizzi gli algoritmi ECDSA, l'algoritmo determina il tipo di chiave pubblica e privata che devi specificare:

Algoritmo Curva Requisito della chiave
ES256 P-256 Una chiave generata dalla curva P-256 (nota anche come secp256r1 o prime256v1)
ES384 P-384 Una chiave generata dalla curva P-384 (nota anche come secp384r1)
ES512 P-521 Una chiave generata dalla curva P-521 (nota anche come secp521r1)

Algoritmi di crittografia delle chiavi

I criteri JWS/JWT supportano tutti gli algoritmi di crittografia delle chiavi supportati da OpenSSL.

Utilizzare un set di chiavi web JSON (JWKS) per verificare un JWS/JWT

Quando verifichi un JWS/JWT firmato, devi fornire la chiave pubblica che è associata alla chiave privata utilizzata per firmare il token. Hai due opzioni per fornire la chiave pubblica ai criteri di verifica JWS/JWT:

  • Utilizza il valore effettivo della chiave pubblica (in genere fornito in una variabile di flusso) oppure
  • Utilizza una chiave pubblica racchiusa in un JWKS.

Informazioni su JWKS

Un JWKS è una struttura JSON che rappresenta un insieme di chiavi web JSON (JWK). Un JWK è una struttura di dati JSON che rappresenta una chiave di crittografia. JWK e JWKS sono descritti in RFC7517. Vedi gli esempi di JKWS nell' Appendice A. Esempi di set di chiavi web JSON

Struttura JWKS

RFC7517 descrive gli elementi chiave JWKS per ogni tipo di chiave, ad esempio "RSA" o "EC". Ad esempio, a seconda del tipo di chiave, questi parametri possono includere:

  • kty : il tipo di chiave, ad esempio "RSA" o "EC".
  • kid (l'ID chiave): può essere qualsiasi valore arbitrario (senza duplicati all'interno di un set di chiavi). Se il JWT in entrata contiene un ID chiave presente nel set di JWKS, il criterio utilizzerà la chiave pubblica corretta per verificare la firma JWS/JWT.

Di seguito sono riportati esempi di elementi facoltativi e dei relativi valori:

  • alg : l'algoritmo della chiave. Deve corrispondere all'algoritmo di firma nel JWS/JWT.
  • use : se presente, deve essere sig.

Il seguente JWKS include gli elementi e i valori obbligatori e sarebbe valido su Edge (da 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",
      }
   ]
}

Progettare il proxy per utilizzare JWKS

Quando un JWS/JWT viene ottenuto da un emittente, spesso l'emittente inserisce un ID chiave (o kid) nell'intestazione JWS/JWT. La chiave indica al destinatario del JWS/JWT come trovare la chiave pubblica o segreta necessaria per verificare la firma sul JWS/JWT firmato.

Ad esempio, supponiamo che un emittente firmi un JWT con una chiave privata. L'"ID chiave" identifica la chiave pubblica corrispondente da utilizzare per verificare il JWT. L'elenco delle chiavi pubbliche è in genere disponibile in un endpoint noto, ad esempio: https://www.googleapis.com/oauth2/v3/certs.

Questa è la sequenza di base che Edge (o qualsiasi piattaforma che funziona con JWKS) deve eseguire per utilizzare un JWS/JWT con un JWKS:

  1. Esamina l'intestazione JWS/JWT per trovare l'ID chiave (kid).
  2. Esamina l'intestazione JWS/JWT per trovare l'algoritmo di firma (alg), ad esempio RS256.
  3. Recupera l'elenco di chiavi e ID dal JWKS dell'endpoint noto per un determinato emittente.
  4. Estrai la chiave pubblica dall'elenco di chiavi con l'ID chiave annotato nell'intestazione JWS/JWT e con l'algoritmo corrispondente, se la chiave JWKS specifica l'algoritmo.
  5. Utilizza la chiave pubblica per verificare la firma sul JWS/JWT.

Come sviluppatore di proxy API Edge, devi eseguire le seguenti operazioni per eseguire la verifica JWS/JWT:

  1. Recupera l'elenco di chiavi e ID dall'endpoint noto per un determinato emittente. Per questo passaggio puoi utilizzare un criterio Service Callout.
  2. Nel criterio Verify JWS/JWT, specifica la posizione del JWS/JWT nell'elemento <Source> e il payload JWKS nell'elemento <PublicKey/JWKS>. Ad esempio, per il criterio 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>

Il criterio Verify JWT esegue tutte le altre operazioni:

  • Se nel JWKS non viene trovata una chiave con un ID chiave corrispondente all'ID chiave (kid) dichiarato nel JWT, il criterio Verify JWT genera un errore e non convalida il JWT.
  • Se il JWT in entrata non contiene un ID chiave (kid) nell'intestazione, questo mapping di ID chiave-chiave di verifica non è possibile.

In qualità di progettista del proxy, sei responsabile della determinazione della chiave da utilizzare; in alcuni casi questo potrebbe trattarsi di una chiave fissa e hardcoded.