Importante : Abbiamo appena lanciato UserEncrypted.com . un servizio gratuito di criptazione lato utente per salvare in rete in sicurezza note o "password". La peculiarità del servizio risiede nel fatto che i vostri dati "in chiaro" non lasceranno mai il vostro computer, e solo i dati criptografati transiteranno sulla rete.
Recentemente mi è capitato di lavorare su un applicativo web in cui il commissionante era una società che conservava dati sensibili dei propri clienti. I dati dovevano essere accessibili ai rispettivi proprietari e nessun altro a nessun livello, incluso il database. La piattaforma era LAMPJ (Linux, Apache, Mysql, PHP più alcuni "webservice" Java interrogati dal PHP), e si richiedeva crittografia AES protetta da password. Proposte Le 2 soluzioni proposte erano: - crittografia su database utilizzandola funzione di mysql "aes_encrypt"
- crittografia lato utente
La crittografia su database fu subito scartata perchè tale approccio avrebbe significato un accesso ai dati non criptati da parte del PHP, per cui restava in piedi l'opzione di crittografia lato utente. A questo punto si imponeva una seconda scelta: - un applet java utilizzando le librerie bouncycastle
- crittografia javascript pura
Malgrado abbia una certa esperienza con crittografia, firma digitale e marcatura temporale in Java(e non), ho deciso (inizialmente), a causa ad esempio delle restrizioni internazionali per l'esportazione di alcuni algoritmi di crittografia in Java, di tentare l'approccio Javascript. Naturalmente non mi è passato per la testa neanche per un istante di implementare da me un algoritmo, ed ho trovato il codice giusto a Movable Type Scripts, dove potrete trovare il codice sorgente completo. Il codice è chiaro e molto semplice da usare. Abbiamo fondamentalmente bisogno di 2 metodi : AESEncryptCtr and AESDecryptCtr. Utilizzo pratico
A questo punto si trattava solo di come gestire i dati sensibili. Per semplificare,immaginiamo una "form" html con un campo nascosto contenente i dati crittografati ed una "textarea" per il testo in chiaro. Lato server avremo un semplice file di testo come esempio di base di dati. Nell'esempio utilizziamo PHP, ma la sostanza non cambia per differenti tecnologie sul server. Un'ultima cosa, per evitare problemi con caratteri speciali, il testo crittografato lo codificheremo in base64, sempre lato utente. Per fare ciò ci serviremo del codice javascript gentilmente rilasciato al pubblico dominio da Tyler Akins. Detto ciò i nostri file saranno: - base64.js - here contenente le funzioni di codifica/decodificabase64
- encrypt.js - quì il codice scaricato da Movable Type Scripts
- encrypt.txt - il nostro file di contenuti. Conterrà i dati crittografati e verrà creato dal PHP
- encrypt.php - quì la nostra interfaccia web, con php e html (orribilmente) mischiati.
Ecco il codice del file encrypt.php :
1:<?php 2: 3: 4: $filePath=$_SERVER['DOCUMENT_ROOT']."/demo/encryption/encryption.txt"; 5: if(isset($_POST['encrypted_data'])){ 6: file_put_contents($filePath,$_POST['encrypted_data']); 7: } 8: $text=(file_exists($filePath)) ? file_get_contents($filePath): ""; 9:?> 10:<html> 11:<script src="base64.js"></script> 12:<script src="encryption.js"></script> 13:<body onload="getPassword();decryptData();"> 14: <form method=POST name=myform> 15: <input type=hidden name=encrypted_data id=encrypted_data value="<?php echo $text;?>"> 16: </form> 17: <textarea id=datafield name=datafield rows=20 cols=50></textarea> 18: <input type=button onclick="return encryptData();" value="submit" > 19: 20: 21:<script language=javascript> 22: var hiddenfield=document.getElementById("encrypted_data"); 23: var textarea=document.getElementById("datafield"); 24: var password=""; 25: function decryptData(){ 26: if(hiddenfield.value !=''){ 27: textarea.value=AESDecryptCtr(decode64(hiddenfield.value), password ,128); 28: } 29: } 30: 31: function encryptData(){ 32: hiddenfield.value=encode64(AESEncryptCtr(textarea.value, password ,128)); 33: document.forms.myform.submit(); 34: } 35: 36: function getPassword(){ 37: password=prompt("Password"); 38: } 39: 40:</script> 41:</body> 42:</html> Prima la parte php: Alla riga 4 definiamo il percorso del file che conterrà i dati crittografati sul server( da personalizzare a seconda delle esigenze). Questo è il caso più semplice. Un esmpio più "reale" contemplerebbe lettura/scrittura su database, ma questo non è influente ora. Nelle righe 5-7 controlliamo se è stato "postato" del testo ed eventualmente lo salviamo nel nostro file di testo. Alla riga 8 leggiamo l'eventuale contenuto del file per poi caricarlo sul nostro campo html nascosto(vedere sotto). Ed ora la parte html/javascript . Includiamo base64.js and encryption.js , creiamo una form con un campo nascosto,che conterrà il testo crittografato in ingresso ed uscita, e fuori dalla form una "textarea" per mostrare/aggiornare il testo in chiaro. Come possiamo vedere alla riga 13, a fine caricamento della pagina (evento onload), prima chiamiamo la funzione getPassword , che richiederà una password, poi la funzione decryptData. Questa leggerà il valore del campo nascosto, lo decoderà da base64 e, mediante la password inserita, cercherà di decrittografarlo e metterlo nella textarea. Il terzo parametro di AESDecryptCtr è il numero di bit della chiave di crittografia(128, 192 e 256 sono supportati). Ora modificando il testo nella textarea e inviando la form, il nuovo testo della textarea verrà crittografato, sempre con la password inserita precedentemente, encodato base64 e messo nel campo nascosto(funzione encryptData). Poi la form verrà inviata, e così al server arriverà solo testo crittografato (la textarea, contenente il testo in chiaro, non fa parte della form e quindi il suo valore non viene inviato al server). Facile, no? Solo un paio di note: 1) se avete una vecchia versione del php, potreste non avere le funzioni file_get_contents and file_put_contents . In questo caso potete trovarle in questo pacchetto PEAR . 2) Assicuratevi di avere i permessi di scrittura sul file che utilizzerete lato server Amici, per oggi è tutto. P.S.:alla fine, per il mio progetto, il commissionante ha richiesto PKI e crittografia mediante certificati su smart card, per cui ho implementato un applet java utilizzando le librerie BouncyCastle e l'interfaccia PKCS11 di IAIK. Per cui ora gli utenti possono crittografare utilizzando la chiave pubblica di tutti coloro che devono poter decrittografare i dati... Di questo scriverò presto in un altro articolo. |