Verifica lato consumatore
Per ricostruire e verificare l”objectId di un segnale a partire da un identificativo candidato, si riporta uno pseudocodice in linguaggio Java che illustra, passo per passo, le operazioni da eseguire.
// === DATI IN INGRESSO ===
String algorithm = response.cryptoHashFunction(); // es. "SHA-256"
String seed = response.seed(); // "Xzzh3pQqLp+VK7gG9NwR6w=="
// !! da trattare come dato opaco, NON va decodificato !!
String originalId = "RSSMRA80A01H501Z"; // identificativo candidato in chiaro
String signalObjectId = signal.objectId(); // "LAa/aPrxlEvOKacO1KFhEJDVj+UqHXg30Ksb7kE1+z8="
// !! da trattare come dato opaco, NON va decodificato !!
// === STEP 1 — Composizione dell'input dell'hash ===
//
// Si concatenano l'identificativo originale e il seed COME STRINGHE,
// poi si convertono in byte UTF-8 in un'unica passata.
//
// IMPORTANTE: il seed NON viene decodificato Base64.
// Si usano i byte ASCII della stringa così come sono.
byte[] input = (originalId + seed).getBytes(StandardCharsets.UTF_8);
// === STEP 2 — Calcolo del digest ===
MessageDigest md = MessageDigest.getInstance(algorithm);
byte[] digest = md.digest(input);
// === STEP 3 — Encoding Base64 dell'output e confronto ===
String candidate = Base64.getEncoder().encodeToString(digest);
boolean match = candidate.equals(signalObjectId);
// Se match == true, l'identificativo originale fornito è effettivamente
// il soggetto a cui il segnale fa riferimento.
Lo stesso codice in forma compatta:
public static boolean matches(String signalObjectId,
String candidateOriginalId,
String seed,
String algorithm) throws NoSuchAlgorithmException {
byte[] input = (candidateOriginalId + seed).getBytes(StandardCharsets.UTF_8);
byte[] digest = MessageDigest.getInstance(algorithm).digest(input);
return Base64.getEncoder().encodeToString(digest).equals(signalObjectId);
}
Errore tipico da evitare
L’errore più comune consiste nel decodificare il seed Base64 prima di passarlo alla funzione di hash. Si tratta di un’operazione sbagliata: il seed esposto da GovWay è una stringa testuale e i suoi caratteri Base64 vanno utilizzati così come sono, in quanto già parte integrante del materiale crittografico contrattualizzato con il consumatore.
// ❌ SBAGLIATO: decodificare il seed prima di passarlo all'hash
byte[] seedBytes = Base64.getDecoder().decode(seed); // <-- NON FARLO
byte[] input = concat(originalId.getBytes(UTF_8), seedBytes);
byte[] digest = MessageDigest.getInstance("SHA-256").digest(input);
String candidate = Base64.getEncoder().encodeToString(digest);
Codice di questo tipo produrrebbe un candidate differente dall”objectId pubblicato nel segnale, facendo fallire la verifica anche per identificativi corretti. La regola mnemonica è semplice: seed e objectId si trattano sempre come stringhe opache; l’unica chiamata a Base64.getEncoder() avviene sull’output binario dell’hash e l’unico confronto è una equals fra stringhe.