Creazione di una classe Crypter con PHP

In questo articolo spiegherò come creare una classe PHP che crittografa e decodifica tutti i dati con una determinata password. È oggetto programmato e utilizza algoritmi PHP esistenti.


introduzione

Pensa a cosa potremmo avere bisogno di una classe come questa? Vogliamo crittografare i dati importanti con una password per motivi di sicurezza. Vogliamo anche, come già accennato, essere in grado di decifrare quei dati quando necessario. Perché dovresti usare algoritmi simmetrici? È facile; quando offri una password inviata via email o qualcosa di simile, devi inserire la password in testo in chiaro. Gli algoritmi di hash non sono reversibili. Una volta che hai cancellato una stringa, non puoi decifrare il testo originale dall'hash.

Forse hai già sentito parlare di MD5? Non è più l'opzione migliore perché tende a essere insicuro. Ci sono database sul Web - che non voglio menzionare - che possono essere utilizzati per recuperare il testo in chiaro da un hash semplicemente digitando l'hash in una casella di ricerca. Quindi dovresti usare qualcosa come SHA che è stato sviluppato dalla NSA (National Security Agency). SHA è l'abbreviazione di Secure Hash Algorithm ed è uno degli algoritmi hash più sicuri. Ce ne sono anche altri, come WHIRLPOOL, PANAMA e RIPEMD, ma SHA è attualmente lo standard sicuro per gli hash e viene utilizzato in numerose applicazioni.


Passaggio 1: preparazione

Penso che sia importante creare un'interfaccia. Questo perché possiamo sempre usare i metodi che sono definiti nell'interfaccia senza pensare, quando si instanzia un oggetto di una classe, che implementa quell'interfaccia.

Quando una classe implementa un'interfaccia, deve implementare i metodi forniti in quell'interfaccia, altrimenti si verificherà un errore! Quindi ecco un esempio:

 interfaccia ICrypter funzione pubblica Encrypt ($ data); funzione pubblica Decrypt ($ data);  classe Crypter implementa ICrypter funzione pubblica Encrypt ($ data) ... funzione pubblica Decrypt ($ data) ...

Come puoi vedere, l'interfaccia istruisce le classi che implementano ICrypter per fare in modo che la funzione pubblica Cifra con un parametro $ data. Anche la funzione pubblica Decrypt ha il parametro $dati. Puoi provarlo; se alla classe manca uno dei metodi specificati nell'interfaccia, si ottiene un errore fatale. Ecco un esempio:

Errore irreversibile: Class Crypter contiene 1 metodo astratto e deve pertanto essere dichiarato astratto o implementare i restanti metodi (ICrypter :: Decrypt) in C: \ www \ Nettuts \ Crypter \ crypter.php sulla riga 32.

Bel errore, giusto? Quindi puoi essere sicuro che le classi hanno davvero i metodi!


Passaggio 2: password per la crittografia e la decrittografia

Come ho detto prima, vogliamo essere in grado di utilizzare una password specifica per la crittografia e la decrittografia. Questa password deve essere accessibile per la funzione encrypt- e decrypt, quindi definiremo una variabile di istanza, chiamata chiave, che viene passata al costruttore. La definizione di $ chiave è necessario solo nel Crypter Classe:

 chiave privata $;

Tuttavia, la definizione del costruttore deve essere nell'interfaccia. Pertanto, è necessario anche nella classe, perché dobbiamo implementare tutto ciò che abbiamo definito nell'interfaccia. L'interfaccia conterrà:

 funzione pubblica __construct ($ chiave);

e la classe:

 funzione pubblica __construct ($ chiave) ...

Ora che sappiamo di avere una chiave, possiamo usarla per crittografare e decifrare!


Passaggio 3: costruttore

Nel costruttore dobbiamo impostare la chiave e scegliere un algoritmo. Useremo l'algoritmo Blowfish per questo esempio e lo useremo come valore standard. Spiegherò un po 'di più sugli algoritmi simmetrici più avanti nel testo, ma per semplicità useremo Blowfish. Puoi cambiarlo più tardi se lo desideri. Quindi abbiamo bisogno di un'altra variabile di istanza chiamata Algo:

 $ Algo privato;

e il costruttore ...

 funzione pubblica __construct ($ Key, $ Algo = MCRYPT_BLOWFISH) $ this-> Key = substr ($ Key, 0, mcrypt_get_key_size ($ Algo, MCRYPT_MODE_ECB)); $ this-> Algo = $ Algo; 

La lunghezza della chiave dipende dall'algoritmo e dalla modalità di crittografia. In questo esempio useremo la modalità ECB. Puoi creare questa variabile come abbiamo già fatto con l'algoritmo. Usiamo la sottostringa della chiave data con la lunghezza massima consentita. Puoi ottenere questa lunghezza con il mcrypt_get_key_size funzione che richiede l'algoritmo e la modalità di crittografia come parametri.

Ora diamo alla nostra variabile di istanza Key la chiave corretta per l'algoritmo e assegniamo la nostra variabile di istanza Algo.

Quindi ora abbiamo il costruttore. Come ho detto in precedenza, puoi modificare il valore standard di Algo in qualsiasi altro algoritmo supportato da MCrypt.

Elenco di algoritmi supportati da php.net:

  • MCRYPT_3DES
  • MCRYPT_ARCFOUR_IV (solo libmcrypt> 2.4.x)
  • MCRYPT_ARCFOUR (solo libmcrypt> 2.4.x)
  • MCRYPT_BLOWFISH
  • MCRYPT_CAST_128
  • MCRYPT_CAST_256
  • MCRYPT_CRYPT
  • MCRYPT_DES
  • MCRYPT_DES_COMPAT (solo libmcrypt 2.2.x)
  • MCRYPT_ENIGMA (solo libmcrypt> 2.4.x, alias per MCRYPT_CRYPT)
  • MCRYPT_GOST
  • MCRYPT_IDEA (non libero)
  • MCRYPT_LOKI97 (solo libmcrypt> 2.4.x)
  • MCRYPT_MARS (solo libmcrypt> 2.4.x, non libero)
  • MCRYPT_PANAMA (solo libmcrypt> 2.4.x)
  • MCRYPT_RIJNDAEL_128 (solo libmcrypt> 2.4.x)
  • MCRYPT_RIJNDAEL_192 (solo libmcrypt> 2.4.x)
  • MCRYPT_RIJNDAEL_256 (solo libmcrypt> 2.4.x)
  • MCRYPT_RC2
  • MCRYPT_RC4 (solo libmcrypt 2.2.x)
  • MCRYPT_RC6 (solo libmcrypt> 2.4.x)
  • MCRYPT_RC6_128 (solo libmcrypt 2.2.x)
  • MCRYPT_RC6_192 (solo libmcrypt 2.2.x)
  • MCRYPT_RC6_256 (solo libmcrypt 2.2.x)
  • MCRYPT_SAFER64
  • MCRYPT_SAFER128
  • MCRYPT_SAFERPLUS (solo libmcrypt> 2.4.x)
  • MCRYPT_SERPENT (solo libmcrypt> 2.4.x)
  • MCRYPT_SERPENT_128 (solo libmcrypt 2.2.x)
  • MCRYPT_SERPENT_192 (solo libmcrypt 2.2.x)
  • MCRYPT_SERPENT_256 (solo libmcrypt 2.2.x)
  • MCRYPT_SKIPJACK (solo libmcrypt> 2.4.x)
  • MCRYPT_TEAN (solo libmcrypt 2.2.x)
  • MCRYPT_THREEWAY
  • MCRYPT_TRIPLEDES (solo libmcrypt> 2.4.x)
  • MCRYPT_TWOFISH (per versioni precedenti di mcrypt 2.x, o mcrypt> 2.4.x)
  • MCRYPT_TWOFISH128 (TWOFISHxxx è disponibile nelle versioni 2.x più recenti, ma non nelle versioni 2.4.x)
  • MCRYPT_TWOFISH192
  • MCRYPT_TWOFISH256
  • MCRYPT_WAKE (solo libmcrypt> 2.4.x)
  • MCRYPT_XTEA (solo libmcrypt> 2.4.x)

Quindi quale dovremmo usare quando vogliamo usare la classe Crypter nei nostri prodotti? Al momento AES è lo standard degli algoritmi simmetrici. È usato in molte applicazioni, ma dov'è AES? AES è stato originariamente pubblicato come Rijndael che è elencato. È un algoritmo molto veloce, ma sicuro, ed è persino veloce con dimensioni della chiave a 256-bit. Il mio consiglio è di usare MCRYPT_RIJNDAEL_256 per le vostre applicazioni. Proprio come un esempio, AES è utilizzato in WPA2, che è uno standard di sicurezza per WLAN.


Passaggio 4: ora alla crittografia

La prima cosa da verificare: ci sono dati da crittografare? In caso contrario, è possibile andare avanti e interrompere la crittografia. Se si desidera utilizzare altre modalità di crittografia, è necessario aggiungere il seguente codice.

 $ iv_size = mcrypt_get_iv_size ($ this-> Algo, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);

Questo $ iv viene utilizzato ad esempio in CBC, CFB, OFB e in alcuni algoritmi in modalità di crittografia STREAM. Se il parametro non viene passato in queste modalità, il $ iv sarà impostato su '\ 0'. Il prossimo passo è criptare i dati con la semplice funzione mcrypt_encrypt. Qui abbiamo bisogno del nostro algoritmo, la chiave, i dati e una modalità di crittografia. $ iv è facoltativo.

 $ crypt = mcrypt_encrypt ($ this-> Algo, $ this-> Key, $ data, MCRYPT_MODE_ECB, $ iv);

Infine codifica i dati crittografati con base64_encode e tagliali prima di restituirli.

 return trim (base64_encode ($ crypt));

Dobbiamo codificare in base64 i dati crittografati per ottenere dati sicuri per l'URL. Ciò è necessario perché, se si desidera utilizzare i dati crittografati, ad esempio in un URL, si avranno problemi con "&" poiché si tratta di un carattere riservato specificato nell'RFC. Quindi hai bisogno di qualcosa come i caratteri alfanumerici - in altre parole, personaggi che sono al sicuro. La codifica base64 fornisce questi caratteri sicuri, ed è per questo che la stiamo usando. Non sappiamo cosa verrà fatto con i dati dopo la crittografia.


Passaggio 5: la decrittografia è crittografia invertita

Ancora una volta poniamo la stessa prima domanda. Ci sono dati? Se c'è, devi basare 64_decode i dati come abbiamo codificato in precedenza con base64_encode.

 $ crypt = base64_decode ($ data);

Quindi la parte facoltativa con $ iv.

 $ iv_size = mcrypt_get_iv_size ($ this-> Algo, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND);

Decrittografia con la semplice funzione mcrypt_decrypt. Qui abbiamo bisogno - quasi - degli stessi parametri. La differenza è che la funzione di decrittografia deve accedere ai dati criptati piuttosto che ai dati originali. Quindi qui di nuovo usiamo, l'algoritmo, la chiave, i dati criptati, la modalità di crittografia e l'iv opzionale.

 $ decrypt = mcrypt_decrypt ($ this-> Algo, $ this-> Key, $ crypt, MCRYPT_MODE_ECB, $ iv);

Infine restituisci i dati ritagliati e decrittografati.

 return trim ($ decrypt);

Esempi

Definisci una Crypter globale. In questo esempio utilizzeremo RIJNDAEL_256 (AES) con la password "Qualsiasi password". Dopo l'istanza chiamate le vostre funzioni o metodi per testarlo. Qui chiamiamo la funzione foo e il metodo foo1.

 $ crypter = new Crypter ("Any password", MCRYPT_RIJNDAEL_256); foo (); $ foo = new Foo (); $ Foo-> foo1 ();

Puoi ottenere il tuo criptor dalla variabile Superglobal chiamata $ GLOBALS. Questo è un array associativo, quindi puoi chiamare tutte le tue variabili globali con il nome con cui le hai definite. Puoi recuperare il $ crypter che è definito al di fuori del blocco foo o foo1 con $ GLOBALS [ "crypter"]...

 function foo () ... $ encrypted = $ GLOBALS ["crypter"] -> Encrypt ($ data); $ decrypted = $ GLOBALS ["crypter"] -> Decrypt ($ encrypted); ... class Foo public function foo1 () ... $ encrypted = $ GLOBALS ["crypter"] -> Encrypt ($ data); $ decrypted = $ GLOBALS ["crypter"] -> Decrypt ($ encrypted); ...

Conclusione

Ora hai una lezione completa di Crypter e puoi crittare e decodificare tutte le volte che vuoi! Scarica il codice sorgente completo con un buon esempio se non vuoi scriverlo da solo. Spero che ti sia piaciuto questo articolo.