Delphi import unit per OpenSSL DLL (Cifrare il codice fiscale per l'invio delle ricette mediche al MEF)

Cifrare il codice fiscale per l'invio delle ricette mediche al MEF

Il Ministero dell'Economia e delle Finanze, nel Decreto del 24 giugno 2004, aggiornato il 27 luglio 2005, prevede che il software gestionale delle strutture sanitarie "dovra' conservare il codice fiscale utilizzando tecniche di crittografia con la chiave pubblica RSA contenuta nel certificato X.509 fornito dal MEF ed applicando il padding PKCS#1 v 1.5. La trasformazione deve essere conforme con quella ottenuta dall'esecuzione del comando del pacchetto open source "openssl", come a titolo di esempio:

- openssl rsautl -encrypt -in CF.txt -out CF.enc -inkey MEF.cer -certin -pkcs

in cui il file CF.txt contiene il codice fiscale in chiaro, il file MEF.cer contiene il certificato X.509 del MEF, il file CF.enc contiene il risultato dell'operazione di crittografia sul codice fiscale. Il codice fiscale crittografato dovra' essere codificato BASE64 (RFC 1521) per poter essere inserito nel file XML da inviare telematicamente al MEF."

.

Dev'essere la prima volta che una norma italiana nomina esplicitamente un determinato programma opensource...

Il testo completo del decreto è disponibile in formato PDF sul sito del Ministero.

Per quanto sia possibile scrivere un wrapper che invochi direttamente openssl, questa scelta è molto penalizzante per le prestazione. Chi usa Borland Delphi per generare i file XML da inviare la Ministero può usare direttamente le funzioni della libreria dinamica di openssl adattando l'esempio di cifra RSA, ma visto l'interesse che l'argomento ha sollevato, qui si trova una soluzione specifica.

Legalese

Attenzione: verificate accuratamente che i risultati siano effettivamente identici a quelli generati direttamente da openssl. L'autore, non potendo controllare gli ambienti e i sistemi in cui viene utilizzato questo codice, non si assume nessuna responsabilità sul suo funzionamento.

Il codice in questa pagina può essere usato liberamente per sviluppare un applicazione conforme al Decreto; comunque è gradita una citazione tipo "Questo programma contiene parti sviluppate da CSITA/DISI - Università di Genova"

Istruzioni

Scaricate i file libeay32.pas e CryptoUtils.pas.

Se non è già installata per qualche altro motivo, procuratevi una versione della DLL di OpenSSL come spiegato nell'introduzione.

(******************************************************************************
 Author: Marco Ferrante
 2002-2006 CSITA - Università di Genova (IT).
 2007 DISI - Università di Genova (IT).
 http://www.disi.unige.it/
 ******************************************************************************)
uses
  libeay32, CryptoUtils;

{
  Ricordate di invocare InitOpenSSL; prima di usare
  qualsiasi funzione di openssl. Per liberare le risorse, si pu� invocare
  FreeOpenSSL;

  Per caricare la chiave pubblica da un certificato X509:
    key := GetPublicKey(CreateFileInputBio(nomefile), FORMAT_X509);
  per caricarla da un file PEM:
    key := GetPublicKey(CreateFileInputBio(nomefile), FORMAT_PEM);
  per caricare la chiave privata da un file PEM cifrato
    key := GetPrivateKey(CreateFileInputBio(nomefile), FORMAT_PEM, password);
}

function CifraCF(CFtxt: string; key: pEVP_PKEY): string;
var
  cleartext, crypted: pBIO;
  b64: pBIO;
begin
try
  cleartext := CreateStringInputBio(CFtxt);
  crypted := CreateMemoryOutputBio();

  // Base 64 encoding
  b64 := BIO_new(BIO_f_base64());
  RSAEncrypt(key, cleartext, BIO_push(b64, crypted), RSA_PKCS1_PADDING); // concat B64 encoding
  BIO_flush(b64);

  result := GetStringFromBio(crypted);
finally
  BIO_free(cleartext);
  BIO_free_all(crypted);
  EVP_PKEY_free(key);
  end;
end;

Verifica del funzionamento

Per verificare il funzionamento corretto, avete bisogno di una coppia di chiavi RSA. Potete usare quelle appositamente messe a disposizione dal Ministero o generarle da OpenSSL con il comando:


  openssl genrsa -out private.key 1024

da cui estrarre quella pubblica con


  openssl rsa -in private.key -out public.key -pubout

Cifrate con il vostro programma un testo con la chiave pubblica di test, salvate il risultato in un file di testo dal nome cifrato.txt, quindi, nuovamente con OpenSSL, decodificate il file da BASE64 a binario:


openssl enc -a -d -in cifrato.txt -out cifrato.enc

e quindi decifratelo con la chiave privata di test:


openssl rsautl -decrypt -in cifrato.enc -inkey private.key -pkcs

Ovviamente il risultato dovrà essere identico al testo originale.

Suggerimenti, commenti, contributi e, soprattutto, ringraziamenti sono apprezzati; scrivere a marco@csita.unige.it