home | search | help  
home page università di genova

Marco Ferrante
English version Home page
Versione italiana Pagina principale
Cifratura DM 24/06/2004

Delphi/OpenSSL
English version English version
Versione italiana Versione italiana

Moduli di cifra RSA per il codice fiscale

Questo è un elenco dei moduli software disponibili per cifrare il codice fiscale secondo i requisiti del Decreto del 27 luglio 2005 del Ministero dell'Economia e delle Finanze (MEF).
I moduli devono essere in grado di produrre un risultato conforme a:

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

A parte OpenSSL e le sue librerie, la cifratura può essere ottenuta con vari modi. Questo è un elenco delle possibilità di cui siamo a conoscenza.
Quando disponibili, sono segnalati esempi di codice.

L'elenco non è esaustivo. Potete segnalare integrazioni, errori o suggerimenti a ferrante@disi.unige.it.
Ultimo aggiornamento 2007-06-12

Avvertenze

L'inclusione in questo elenco non costituisce una preferenza o una certificazione di conformità all'uso, né l'esclusione costituisce un'indicazione di non adeguatezza.
Data la delicatezza dell'implementazione di algoritmi crittografici, sono da preferirsi moduli forniti con sorgenti ricompilabili o certificati FIPS-140 da laboratori indipendenti. L'elenco dei moduli certificati è disponibile sul sito del NIST.
Il codice fornito nei nostri esempi può essere usato liberamente secondo la licenza indicata. In ogni caso, se inserito in applicazioni, è gradita una vostra segnalazione dell'uso.

Librerie e componenti non utilizzabili

Alcune librerie, anche famose e di qualità, non sembrano adatte alla cifratura del codice fiscale, almeno nella versione corrente. Sono state analizzate:

Controllo ActiveX Microsoft® CAPICOM 2.0
L'oggetto EncryptedData prevede solo algoritmi a chiave simmetrica, mentre l'oggetto SignedData produce solo dei package PKCS#7.
Inoltre, CAPICOM non è supportato sotto Windows Vista.
Riferimento: Algorithm.Name property.
Libreria e componenti Cryptlib 3.3.1 di Peter Gutmann
Non sembra possibile ottenere direttamente la stringa cifrata RSA, che viene sempre imbustata in una struttura PKCS#7. Si veda la risposta di Gutmann ad un problema analogo.

Componenti ActiveX, OCX, ecc...

L'elenco riporta alcuni componenti software commerciali che, in base alla documentazione, dovrebbero essere adatti alla cifratura richiesta.

Activecrypt Software XP_CRYPT
Per Microsoft SQL Server e Oracle. Fornito con sorgenti.
Chilkat RSA ActiveX
Versione trial 30 giorni disponibile
Per caricare la chiave dal certificato, occorre anche il controllo Cert ActiveX, ora compreso nel pacchetto a seguito di una nostra richiesta.
DataFlex Dimatek
Prodotto da un'azienda italiana, nella documentazione cita esplicitamente la cifratura conforme al DM 27 Luglio 2005 e ne riporta un esempio.
EasyByte Cryptocx
Non cifra RSA
Polar Crypto ActiveX e DLL
Versione trial disponibile.
Fornito con sorgenti.
Ultra Shareware Ultra Crypto Component ActiveX
Versione trial disponibile.
Weonlydo wodCrypt ActiveX
Versione trial disponibile.
Comprende un esempio specifico in Visual Basic sulla cifratura RSA.
Xceed Encryption Library COM e ActiveX
Versione trial 45 giorni disponibile (richiede registrazione)

C e C++

Dal momento che il comando rsautl di OpenSSL è scritto in C e che OpenSSL è un progetto open source, è sufficiente prenderne il sorgente, ripulirlo delle parti che non servono e utilizzarlo direttamente. Il corpo del modulo in C++ deve procedere in questo modo:

/*
Differenti versioni di OpenSSL e della DLL usano strutture dati differenti;
conviene considerare tutti i puntatori come opachi.
*/

#define FORMAT_ASN1     1
#define FORMAT_PEM      3

void *load_certificate(char *file, int format)	{
	void *x509 = NULL;
	void *certbio;

	certbio = BIO_new(BIO_s_file())) == NULL);

	BIO_read_filename(certbio, file);

	if (format == FORMAT_ASN1)
		x509 = d2i_X509_bio(certbio, NULL);
	else if (format == FORMAT_PEM)
		x509 = PEM_read_bio_X509_AUX(certbio, NULL, NULL, NULL);
	else
		throw "Formato del certificato sconosciuto.";

	BIO_free(certbio);
	return(x509);
}


int main() {

	char *certfile = "miocertificato.cer";
	char *codicefiscale = "AAAZZZ99X99A000Z";

	// Serve per verifica la versione della libreria
	cout << "Versione di OpenSSL: " << SSLeay_version(SSLEAY_VERSION) <<  endl;
	
	void *x509;
	void *pkey;
	void *rsakey;
	void *crypted;

	ERR_load_CRYPTO_strings();
	OpenSSL_add_all_algorithms();

	x509 = load_certificate(certfile, FORMAT_PEM);
	pkey = X509_get_pubkey(x509);
	X509_free(x509);

	rsakey = EVP_PKEY_get1_RSA(pkey);
	EVP_PKEY_free(pkey);

	// Cifra il testo del codice fiscale
	char *outdata;
	int outdatalen;
	int keysize;

	keysize = RSA_size(rsakey);
	outdata = (char*)OPENSSL_malloc(keysize);
	outdatalen = RSA_public_encrypt(strlen(codicefiscale), codicefiscale,
			outdata, rsakey, RSA_PKCS1_PADDING);
	// A questo punto il valore e' cifrato RSA ma codificato binario (ovvero non codificato)
		
	// Codifica il risultato in Base64
	void *b64;
	crypted = BIO_new(BIO_s_mem());
	b64 = BIO_new(BIO_f_base64());
	BIO_push(b64, crypted);  // Concatena i due BIO
	BIO_write(b64, outdata, outdatalen);
	BIO_flush(b64);
	OPENSSL_free(outdata);

	// Estrae il risultato
	char *result;
	int resultlen;
	resultlen = BIO_pending(crypted);
	result = (char *)malloc(resultlen + 1);
	BIO_read(crypted, result, resultlen);
		
	BIO_free_all(crypted);

	cout << "Risultato:" << endl << result << endl << endl;
		
	free(result);
}

Nell'esempio, tutti i controlli sono stati omessi. Il codice corretto è nel pacchetto con sorgenti e esegubile per Windows compilati con Borland C++ 5.5 (versione free).

Per applicazioni in C++, dovrebbe essere utilizzabile la libreria open source Crypto++® (non testata). Si tratta di una libreria multipiattaforma (Windows, Linux, Solaris, Mac OS X), di cui la versione compilata per Windows, fornita come DLL, è certificata FIPS-140-2 livello 1.

In ambiente Windows, le librerie di base Microsoft® CryptoAPI forniscono le functioni necessarie.

xHarbour

Grazie a Domenico Infante, è stata verificata la compatibilità del modulo C++ riportato sopra con xHarbour.

Microsoft Visual Basic 6 e VBA

La DLL di OpenSSL non è utilizzabile, perché la convenzione di chiamata CDECL è incompatibile con Visual Basic.

In teoria, dovrebbe essere possibile usare le librerie di base di Windows CryptoAPI. In pratica, risulta molto complesso per via dello stile di programmazione richiesto e della mancanza di esempi affidabili. In ogni caso, si possono vedere alcuni thread su newsgroup e forum di programmazione:

In definitiva, la scelta più semplice sembrano i componenti ActiveX commerciali.

Borland Delphi 6 e 7

Può invocare la DLL di OpenSSL. Le funzioni sono definite nella nostra unit d'importazione.. Abbiamo anche già preparato un esempio d'uso.

Si possono usare anche tutti i moduli indicati per Visual Basic 6. Altri approfondimenti:

Java

Le estensioni crittografiche JCE necessarie, comprese nel JDK a partire dalla versione 1.4.
Per la cifratura RSA, il provider JCE standard la permette a partire da Java 5. Per Java 1.4 occorre utilizzare un provider aggiuntivo.

Abbiamo preparato una classe che può servire da esempio o essere utilizzata direttamente:

  • Codice della classe
  • JavaDoc on line
  • Package binario con sorgenti e documentazione
    Si può usare a riga di comando con java -jar cifracf.jar mefpp.cer AAAZZZ99X99A000Z. Per Java 1.4, occorre mettere nel classpath un provider JCE con supporto per RSA.

Piattaforma .NET

La classe System Security.Cryptography.RSACryptoServiceProvider fornisce il servizio necessario. Il metodo Encrypt va invocato con il secondo parametro a false.
Il sito Microsoft MSDN riporta alcuni esempi completi per C# e Visual Basic.

Sybase PowerBuilder 6-7

Valgono le stesse considerazioni di Visual Basic 6

Python

Esiste il wrapper a OpenSSL m2crypto.