DevPortalPagoPA


Tabella dei contenuti

Come firmare una risposta per un fruitore

Nel ModI viene indicato come l'erogatore di un e-service possa l'implementare un pattern per firmare una risposta verso un fruitore che ha effettuato una richiesta.
Il pattern è INTEGRITY REST 02, e ne viene data una dimostrazione in questo tutorial.
Per maggiori informazioni sulla garanzia della risposta, si veda la sezione dedicata. Per la specifica tecnica definita da AgID, si veda la versione più recente delle Linee Guida sull'interoperabilità tecnica delle Pubbliche Amministrazioni — Pattern di sicurezza (paragrafo 5.3, pagg. 44 e seguenti).

Prerequisiti

Si assume che l'erogatore abbia:
  • creato un Portachiavi erogatore (vedi guida);
  • generato almeno un set di materiale crittografico e caricato la relativa chiave pubblica su PDND Interoperabilità all'interno del portachiavi (vedi tutorial);
  • associato il Portachiavi Erogatore all'e-service per la quale vuole firmare la risposta al fruitore (vedi tutorial).

Struttura della risposta

Nel pattern INTEGRITY REST 02, la risposta al fruitore è costituita da:
  • header HTTP Agid-JWT-Signature: contiene un JWT con informazioni relative all'erogatore sulle quali basare le proprie verifiche;
  • header HTTP Digest: contiene un digest calcolato a partire dai dati contenuti nel payload;
  • header HTTP Accept: indica il content-type del payload;
  • payload: contiene i dati veri e propri.

Step 1: creazione dell'hash

Il contenuto del payload viene codificato in una stringa di byte e sottoposto a una funzione di hash utilizzando l'algoritmo SHA-256. Ad esempio, un payload come
1{"testo": "Ciao mondo"}
2
deve essere codificato come
1SHA-256=cFfTOCesrWTLVzxn8fmHl4AcrUs40Lv5D275FmAZ96E=
2
come previsto dall'RFC-3230.

Step 2: inserimento dell'hash nell'header "Digest"

L'hash appena calcolato viene inserito così com'è nell'header Digest, ossia:
1Digest: SHA-256=cFfTOCesrWTLVzxn8fmHl4AcrUs40Lv5D275FmAZ96E=
2

Step 3: definizione dell'header "Agid-JWT-Signature"

L'header Agid-JWT-Signature è un token che contiene alcune informazioni relative all'erogatore e alla firma, ossia
1Agid-JWT-Signature: eyJhbGciOiJSUzI1NiIsInR5c.vz8...
2
Nello specifico, questo token contiene i seguenti campi:
CampoSignificato campo
algl'algoritmo usato per firmare il JWT
typil tipo di oggetto che si sta inviando (sempre JWT)
kidl'id della chiave pubblica depositata nel portachiavi erogatore corrispondente alla privata con la quale si è firmato questo JWT

Payload

CampoSignificato campo
audl'indirizzo della risorsa contattata
iatl'issued at, il timestamp riportante data e ora in cui viene creato il token, espresso in UNIX epoch (valore numerico, non stringa)
nbf(opzionale) il not before, il timestamp riportante data e ora alla quale diventa attivo il token, espresso in UNIX epoch (valore numerico, non stringa)
expl'expiration, il timestamp riportante data e ora di scadenza del token, espresso in UNIX epoch (valore numerico, non stringa)
signed_headersun oggetto contenente due campi: digest e content-type. Digest è valorizzato con l'hash calcolato allo step 2. Content-type è il content type del payload della risposta (ad esempio application/json, application/octet-stream)

Esempio

1Header
2{
3 "alg": "RS256",
4 "typ": "JWT",
5 "kid": "199d08d2-9971-4979-a78d-e6f7a544f296"
6}
7
8Payload
9{
10 "aud": "https://api.erogatore.example/rest/service/v1/hello/echo"
11 "iat": 1516239022,
12 "nbf": 1516239022,
13 "exp": 1516239024,
14 "signed_headers": [
15   { "digest": "SHA-256=cFfTOCesrWTLVzxn8fmHl4AcrUs40Lv5D275FmAZ96E=" },
16   { "content-type": "application/json" }
17 ],
18}
19

Step 4: firma del token da inserire in "Agid-JWT-Signature"

Il JWT creato al punto precedente viene firmato con la chiave privata corrispondente alla pubblica depositata nel portachiavi erogatore, il cui kid deve corrispondere a quello inserito nell'header kid del JWT.

Step 5: predisposizione della risposta

La risposta sarà quindi composta da:
1Accept: application/json
2Agid-JWT-Signature: eyJhbGciOiJSUzI1NiIsInR5c.vz8...
3Digest: SHA-256=cFfTOCesrWTLVzxn8fmHl4AcrUs40Lv5D275FmAZ96E=
4Content-Type: application/json
5

Payload

1{"testo": "Ciao mondo"}
2
Per maggiori dettagli sulle verifiche che il fruitore farà, si rimanda al tutorial dedicato.

Hai bisogno di aiuto?

Apri un ticket utilizzando l’apposita funzione all’interno della tua Area Riservata

Dicci cosa ne pensi

Per segnalare problemi o dare feedback, puoi aprire una segnalazione su Github