Pdnd api

Buongiorno a tutti,
vi scrivo per sapere se qualcuno può aiutarmi a capire come realizzare un’API Rest di erogazione servizi per la PDND.
In particolare una volta che il fruitore ha il voucher e di conseguenza l’access_token invocherà l’API dell’erogatore sulla base della specifica caricata nel’e-Service (X-Auth-Token inserita nell’header).

Quello che non mi è chiaro è come fa l’API a validare la richiesta? Deve fare un particolare controllo tramite il valore del token?

Non conosco come funziona il mondo del PDND… ma credo che questo post su un altro topic possa aiutarti:

Ho già visto ma non mi spiega bene il funzionamento del controllo dell’access_token

Ciao Elia, il link alla documentazione ufficiale è questo:

Ciao,
sto seguendo la documentazione ma quando effettuo la verifica della firma come indicato nella documentazione che riporto di seguito:
“All’interno del file, l’erogatore cerca l’oggetto che ha lo stesso kid presente nell’header del voucher. In quello stesso oggetto troverà la chiave pubblica al parametro n . Effettuerà dunque una verifica della firma, che la chiave privata usata per firmare il voucher corrisponda a quella pubblica appena ottenuta.”

utilizzando il comando:
$expectedSignature = hash_hmac( ‘sha256’, $base64UrlHeader.“.”.$base64UrlPayload, $signature, true );
dove $signature è il valore del parametro “n” preso dal’url https://uat.interop.pagopa.it/.well-known/jwks.json, mi restituisce un valore di 43 caratteri quando invece la firma che dovrei confrontare dovrebbe essere di 342 caratteri.

Non capisco dove sto sbagliando.

1 Mi Piace

Ciao, hai poi capito? mi sa che sto sbattendo la testa sullo stesso problema, che immagino sia sul formato della chiave pubblica

Buongiorno Marco,
alla fine ho risolto con una libreria di php. Ti riporto uno stralcio di codice:

set_include_path(plugin_dir_path(FILE).“phpseclib”);
include_once(‘Crypt/RSA.php’);
$rsa = new Crypt_RSA();
$public = [
‘n’ => new Math_BigInteger($this->base64_url_decode_signature($n), 256),
‘e’ => new Math_BigInteger($this->base64_url_decode_signature($e), 256),
];
$rsa->loadKey($public);
$rsa->setHash(‘sha256’);
$rsa->setSignatureMode(CRYPT_RSA_SIGNATURE_PKCS1);
if(!$rsa->verify($base64UrlHeader . ‘.’ . $base64UrlPayload, $this->base64_url_decode_signature($base64UrlActualSignature))){



dove il valore della variabile $base64UrlActualSignature è la firma presa dal token Bearer

Saluti

Grazie! mi hai dato la direzione giusta!

Per chi come me vive sul pianeta java la cosa è più o meno

public static PublicKey findDecodeKey( String nString, String eString) throws Exception {
    BigInteger n = new BigInteger(1, Base64.getUrlDecoder().decode(nString));
    BigInteger e = new BigInteger(1, Base64.getUrlDecoder().decode(eString));
    RSAPublicKeySpec key = new RSAPublicKeySpec(n, e);
    KeyFactory factory = KeyFactory.getInstance("RSA");
    return factory.generatePublic(key);
}

Salve.
Quello che non riusciamo a fare (noi sviluppiamo in php), è quanto descritto in questi step:

Sarebbe possibile avere un esempio esplicito di cosa fare? Magari se ci fosse uno script php di esempio sarebbe molto utile.
Grazie

Il flusso in dettaglio

Il fruitore impacchetta le informazioni complementari
Un JWS di esempio può avere header
{
“alg”: “RS256”,
“kid”: “ZmYxZGE2YjQtMzY2Yy00NWI5LThjNGItMDJmYmQyZGIyMmZh”,
“typ”: “JWT”
}
Il payload sarà invece costituito dalle informazioni aggiuntive che il fruitore vuole trasmettere all’erogatore. Il fruitore firma quindi il JWS con una chiave privata. La chiave pubblica corrispondente deve essere depositata su PDND Interoperabilità e avere per kid quello inserito nell’header del JWS.
NB: questa chiave e questo kid non devono necessariamente essere gli stessi con i quali si firma la client assertion al passaggio 3.
Il fruitore calcola l’hash
A partire dalla codifica del JWS (ossia il JWS codificato secondo l’algoritmo inserito nell’header, in genere inizia per ey) il fruitore applica l’algoritmo di hashing SHA256 al JWS, ottenendone un hash non reversibile a lunghezza fissa.
A scopo esemplificativo, è possibile inserire in un terminale il seguente comando, previa installazione del pacchetto openssl
echo -n {JWS} | openssl sha256
per ottenere l’hash del JWS. Ad esempio, a fronte del JWS esempio con codifica
eyJhbGciOiJIUzI1NiIsImtpZCI6IlptWXhaR0UyWWpRdE16WTJZeTAwTldJNUxUaGpOR0l0TURKbVltUXlaR0l5TW1aaCIsInR5cCI6ImF0K2p3dCJ9.eyJqdGkiOiJkc2Zkc2Zkc2ZkcyIsImEiOiJiIn0.2QcY5UpoE2PgJhe1FKnHx-SZZq_NS6AKDTlfFdpVP9Q
si ottiene l’hash a lunghezza fissa
5db26201b684761d2b970329ab8596773164ba1b43b1559980e20045941b8065
NB: la flag -n che viene passata nel primo comando indica che vengano rimosse eventuali “newline” non viste dall’operatore. Un’eventuale “newline” presente nel token fa cambiare il valore dell’hash che poi non corrisponderà all’atto della verifica dell’erogatore.
Il fruitore costruisce la client assertion
Il fruitore prende quindi l’hash appena ottenuto, e lo inserisce nel payload della client assertion nel campo digest.value. Il campo digest.alg per adesso accetta solamente il valore SHA256 (corrispondente all’algoritmo di hashing che è stato applicato al JWS).
{
…[altri campi della client assertion da flusso standard],
“digest”: {
“alg”: “SHA256”,
“value”: “5db26201b684761d2b970329ab8596773164ba1b43b1559980e20045941b8065”
}
}
L’header della client assertion rimane invece invariato rispetto al flusso standard. La client assertion andrà firmata con la chiave privata corrispondente alla pubblica caricata su PDND Interoperabilità il quale kid è nell’header di questa asserzione.
Il fruitore richiede un voucher a PDND Interoperabilità
In questo passaggio non ci sono variazioni rispetto al flusso standard. Il fruitore fa una richiesta di voucher al server autorizzativo di PDND Interoperabilità inviando la client assertion.
PDND Interoperabilità restituisce un voucher al fruitore
Anche in questo passaggio non ci sono variazioni. Da notare che l’unica verifica che PDND Interoperabilità effettua sul campo digest è che rispetti la lunghezza della stringa prevista da SHA256 (64 caratteri).
Il fruitore fa una richiesta di dati all’erogatore
In questo passaggio, il fruitore costruisce una richiesta verso il servizio dell’erogatore secondo quanto descritto nel file di interfaccia e nella documentazione tecnica a corredo fornita dall’erogatore attraverso PDND Interoperabilità.
Nella richiesta inserirà l’header standard Authorization che conterrà come Bearer token il voucher rilasciato da PDND Interoperabilità allo step precedente. Inoltre, il fruitore inserirà il JWS che contiene le informazioni complementari all’interno di un secondo header denominato Agid-JWT-TrackingEvidence.
L’erogatore effettua le verifiche standard
Per questo passaggio, si veda la sezione dedicata nel flusso standard.
L’erogatore effettua le verifiche aggiuntive sul JWS
Dopo aver completato le verifiche standard, l’erogatore può effettuare le verifiche aggiuntive necessarie a garantire l’attendibilità delle informazioni complementari inserite nel JWS aggiuntivo.
Quindi verificherà l’autenticità e la validità della chiave privata con la quale è firmato il JWS. Per farlo:
si autentica sulle API di Interoperabilità come descritto nel flusso dedicato;
effettua una chiamata keys/{kid} dove kid è valorizzato con il kid inserito nell’header del JWS;
ottiene da PDND Interoperabilità una chiave pubblica in risposta all’interno del campo n;
verifica la firma del JWS, effettuata dal fruitore con la chiava privata, con la chiave pubblica appena ottenuta.
Se l’erogatore ottiene un errore con status code 404 - Not found, significa che la chiave non è presente su PDND Interoperabilità e dunque la richiesta è da ritenersi inattendibile.
L’erogatore calcola e confronta l’hash
Se la chiave è presente e corrisponde, può procedere ad una seconda verifica, ossia quella notarile. In pratica, verifica che la traccia depositata su PDND Interoperabilità corrisponda a quella inserita all’interno del voucher rilasciato da PDND Interoperabilità.
Se c’è corrispondenza, vuol dire che le informazioni complementari inserite all’interno del JWS sono effettivamente quelle che il fruitore ha dichiarato su PDND Interoperabilità di aver inserito.
Per farlo, l’erogatore prende il JWS ed effettua la stessa operazione effettuata dal fruitore nel secondo passaggio. Ottiene quindi l’hash non reversibile del JWS.
L’erogatore confronta quindi questo hash con quello presente all’interno del campo digest.value del voucher rilasciato da PDND Interoperabilità presente nell’header Authorization. Se i due hash sono uguali, il fruitore ha reso una dichiarazione che corrisponde ed è tracciata su PDND Interoperabilità.

Buongiorno a tutti,
ho provato a pubblicare un e-service su PDND interoperabilità ma in merito alla citazione qui sopra abbiamo qualche problema: l’unico link a disposizione riporta al Json specificato anche nella documentazione (https://interop.pagopa.it/.well-known/jwks.json).
Per capire se poteva cambiare qualcosa abbiamo fatto richiesta di fruizione per il nostro stesso e-service seguendo tutti i passaggi (client, finalità e chiavi caricate) ma il link non cambia.
Sapete che cosa potremmo aver sbagliato noi? Il processo è corretto o mancano altri passaggi?
Grazie, buona giornata