creazione classe per gestione qr code

This commit is contained in:
Francesco Di Sciascio 2025-07-21 12:29:32 +02:00
parent 7e093539a8
commit 92995d5658

View File

@ -0,0 +1,105 @@
/*
* Click nbfs://nbhost/SystemFileSystem/Templates/Licenses/license-default.txt to change this license
* Click nbfs://nbhost/SystemFileSystem/Templates/Classes/Class.java to edit this template
*/
package puntocassa.utils;
/**
*
* @author assis
*/
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.time.OffsetDateTime;
import java.util.Base64;
import org.json.JSONObject;
public class QrCryptoService {
// Chiave AES 256-bit (32 byte) - hardcoded per test
private static final byte[] AES_KEY = "0123456789ABCDEF0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
// Crea il JSON cifrato da inserire nel QR
public static String createEncryptedQr(String uid, OffsetDateTime issuedAt, OffsetDateTime expiresAt) throws Exception {
// Crea il payload JSON con i dati utente
String payloadJson = new JSONObject()
.put("uid", uid)
.put("issued_at", issuedAt.toString())
.put("expires_at", expiresAt.toString())
.toString();
// Genera un Initialization Vector (IV) da 96 bit
byte[] iv = new byte[12];
new SecureRandom().nextBytes(iv);
// Cifra il payload con AES-GCM
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(AES_KEY, "AES");
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, gcmSpec);
byte[] encrypted = cipher.doFinal(payloadJson.getBytes(StandardCharsets.UTF_8));
// Codifica IV e dati cifrati in Base64
String ivBase64 = Base64.getEncoder().encodeToString(iv);
String encryptedBase64 = Base64.getEncoder().encodeToString(encrypted);
// Costruisce il JSON finale con iv e data
JSONObject qrJson = new JSONObject()
.put("iv", ivBase64)
.put("data", encryptedBase64);
return qrJson.toString(2); // con indentazione
}
// Decifra il JSON e verifica se è ancora valido
public static String decryptAndValidate(String qrJson) throws Exception {
JSONObject obj = new JSONObject(qrJson);
byte[] iv = Base64.getDecoder().decode(obj.getString("iv"));
byte[] encryptedData = Base64.getDecoder().decode(obj.getString("data"));
// Decrittazione con AES-GCM
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(AES_KEY, "AES");
GCMParameterSpec gcmSpec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmSpec);
byte[] decryptedBytes = cipher.doFinal(encryptedData);
// Parsing del payload decifrato
JSONObject payload = new JSONObject(new String(decryptedBytes, StandardCharsets.UTF_8));
String uid = payload.getString("uid");
OffsetDateTime issuedAt = OffsetDateTime.parse(payload.getString("issued_at"));
OffsetDateTime expiresAt = OffsetDateTime.parse(payload.getString("expires_at"));
boolean isExpired = OffsetDateTime.now(expiresAt.getOffset()).isAfter(expiresAt);
return String.format(
"Dati decifrati:\n" +
"- UID: %s\n" +
"- Emesso: %s\n" +
"- Scadenza: %s\n" +
"- Stato: %s\n",
uid,
issuedAt,
expiresAt,
isExpired ? "SCADUTO" : "VALIDO"
);
}
// Test completo della generazione e verifica
public static void main(String[] args) throws Exception {
//data valida
OffsetDateTime issuedAt = OffsetDateTime.now().withNano(0);
//data scaduta
//OffsetDateTime issuedAt = OffsetDateTime.now().minusMinutes(5).withNano(0);
OffsetDateTime expiresAt = issuedAt.plusSeconds(60);
String qrJson = createEncryptedQr("TSTTST91A48A271O", issuedAt, expiresAt);
System.out.println("QR JSON simulato:");
System.out.println(qrJson);
System.out.println("\nVerifica decifratura:");
System.out.println(decryptAndValidate(qrJson));
}
}