====== Libgcrypt e gli algoritmi simmetrici ======
Autore: **//Fabio Di Matteo//** \\ Ultima revisione: **//30/08/2008//** \\ \\
[[http://directory.fsf.org/project/libgcrypt/|Libgcrypt]] è la libreria per la cifratura e decifratura di dati del progetto GNU, con essa si possono usare algoritmi di cifratura simmetrica e asimmetrica. \\
E' una libreria di utilizzo generale, è usata in diversi campi con numerose applicazioni, ma è ancora carente nella documentazione, infatti per quanto un piccolo [[http://www.gnupg.org/documentation/manuals/gcrypt/|manualetto]] esista non ci sono a mio avviso esempi di base per cominciare a sviluppare con libgcrypt.\\ \\
===== Il nostro codice d'esempio =====
Di seguito un listato C di base contenente il codice di due semplici funzioni ''crypt'' e ''decrypt'' che hanno lo scopo di cifrare e decifrare una stringa mediante l'algoritmo [[http://it.wikipedia.org/wiki/Blowfish|Blowfish]] e la sua chiave contenuta nella stringa **char* key** . I prototipi della funzione sono i seguenti:
char* crypt(char* testo, char* key)
char* decrypt(char* testo, char* key)
ecco il codice completo:
**main.c**
#include
#include
#include
/*Una chiave a 128 bit (16 byte o caratteri)*/
void* key="AC614Eertgdfhjui";
char* crypt(char* testo, char* key){
/*Handle per le operazioni*/
gcry_cipher_hd_t hd;
//inizializzazione
gcry_check_version ( NULL );
gcry_cipher_open (&hd,GCRY_CIPHER_BLOWFISH,
GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_CBC_CTS );
//settiamo la chiave
gcry_cipher_setkey (hd, key, strlen(key));
//criptiamo
if (gcry_cipher_encrypt (hd, testo, strlen(testo), NULL, 0)==0){
printf("Criptaggio dati effettuato correttamente.\n");
}else{
printf("Errore nel criptaggio dei dati! \n");
}
//chiusura handle
gcry_cipher_close (hd);
return testo;
}
char* decrypt(char* testo, char* key){
/*Handle per le operazioni*/
gcry_cipher_hd_t hd;
//inizializzazione
gcry_check_version ( NULL );
gcry_cipher_open (&hd,GCRY_CIPHER_BLOWFISH,
GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_CBC_CTS );
//settiamo la chiave
gcry_cipher_setkey (hd, key, strlen(key));
//criptiamo
if (gcry_cipher_decrypt (hd, testo, strlen(testo), NULL, 0)==0){
printf("Decriptaggio dati effettuato correttamente.\n");
}else{
printf("Errore nel criptaggio dei dati! \n");
}
//chiusura handle
gcry_cipher_close (hd);
return testo;
}
int main(int argc, char *argv[]){
/*Le variabili per le stringhe che useremo*/
char testo[256]="FreeMediaLab che passione!";
char testo_criptato[256];
char testo_decriptato[256];
/*Mettiamo il testo criptato nella variabile testocriptato*/
sprintf(testo_criptato, "%s", crypt(testo,key)) ;
/*Mettiamo il testo decriptato nella variabile testodecriptato*/
sprintf(testo_decriptato, "%s", decrypt(testo,key)) ;
/*Stampiamo a video tutto*/
printf("Stringa originale -->%s\n\n",testo);
printf("Stringa criptata --> %s\n", testo_criptato);
printf("Stringa decryptata --> %s\n", testo_decriptato, key);
return 0;
}
===== Gestire gli errori =====
Come si nota dal codice sopraesposto le principali funzioni che si usano per la crittografia sono:
gcry_error_t gcry_cipher_open (gcry_cipher_hd_t *hd, int algo, int mode, unsigned int flags)
gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t h, void *k, size_t l)
gcry_error_t gcry_cipher_encrypt (gcry_cipher_hd_t h, unsigned char *out, size_t outsize, const unsigned char *in, size_t inlen)
queste funzioni restituiscono una valore di tipo ''gcry_error_t'', quindi per gestire gli errori basta scrivere qualcosa del genere:
...
/*Variabile per gestire gli errori*/
gcry_error_t err;
/*poi lanciare le funzioni nei seguenti modi...*/
/*Inizializzazione*/
err = gcry_cipher_open (&hd,GCRY_CIPHER_BLOWFISH,
GCRY_CIPHER_MODE_CBC,GCRY_CIPHER_CBC_CTS );
if (err) {
printf("Inizializzazione fallita: %s\n", gpg_strerror (err));
return;
}
/*Inizializzazione chiave*/
err = gcry_cipher_setkey (hd, key, strlen(key));
if (err) {
printf("Inizializzazione chiave fallita: %s\n", gpg_strerror (err));
return;
}
/*Cifratura*/
err= gcry_cipher_encrypt (hd, testo, strlen(testo), NULL, 0);
if (err) {
printf("Cifratura fallita: %s\n", gpg_strerror (err));
return;
}
...
===== Il makefile per la compilazione dinamica =====
CPP = gcc
OPTS = `libgcrypt-config --cflags --libs`
all:
$(CPP) main.c -o main $(OPTS)
clean:
rm main
===== Il makefile per la compilazione statica =====
Libgcrypt di default viene compilata anche staticamente in due file: ''libgcrypt.a'' e ''libgpg-error.a'', quindi può essere inclusa nei nostri programmi senza creare ulteriori dipendenze. \\
Ecco il makefile, da notare la variabile ''LIBS'' che contiene i percorsi delle librerie.
CPP = gcc
LIBS =/usr/lib/libgcrypt.a /usr/lib/libgpg-error.a
all:
$(CPP) main.c $(LIBS) -o main
clean:
rm main
Il prefix, ovvero la parte di percorso iniziale delle librerie statiche (/usr/ in esempio) può essere ottenuto con il comando ''libgcrypt-config --prefix''