2012-04-03 14 views
14

al momento disponiamo di un sistema di crittografia sui nostri sistemi per crittografare alcuni dati sensibili nella nostra applicazione PHP. Ora abbiamo un nuovo requisito che dobbiamo cambiare il modulo crypt in openssl. Un'altra cosa che è importante sapere è che stiamo usando il cipher blowfish e il modo ecb. Così ho iniziato a testare quali sono le differenze e come posso decifrare le stringhe crittografate con mcrypt con openssl.Sostituisci Mcrypt con OpenSSL

ho usato la funzione standard di PHP:

  • mcrypt_encrypt vs. openssl_encrypt
  • mcrypt_decrypt vs. openssl_decrypt

Entrambi i metodi sono producendo risultati differenti. La seconda cosa è che nel dato cifrario (blowfish) e mode (ecb) in entrambi i tipi sono richieste lunghezze IV diverse (openssl = 0 e mcrypt = 56).

Qualcuno sa come posso modificare facilmente i moduli senza un grande sforzo di migrazione?

Grazie in anticipo!

UPDATE:

Ecco il codice, che ho provato:

<?php 

function say($message){ 
    if(!is_string($message)){ 
     if(!isset($_SERVER["HTTP_USER_AGENT"])) echo "<pre>"; 
     echo var_export($message, true) . ((!isset($_SERVER["HTTP_USER_AGENT"]) ? "\n" : "<br />")); 
     if(!isset($_SERVER["HTTP_USER_AGENT"])) echo "</pre>"; 
    }else{ 
     echo $message . ((!isset($_SERVER["HTTP_USER_AGENT"]) ? "\n" : "<br />")); 
    } 
} 

say("= Begin raw encryption"); 
$key = "anotherpass"; 
$str = "does it work"; 

say(" Params:"); 
say(" - String to encrypt '".$str."'"); 
say(" - Key: ".$key); 
say(""); 


$params = array(
    "openssl" => array(
     "cipher" => "BF", 
     "mode"  => "ECB", 
    ), 
    "mcrypt" => array(
     "cipher" => "blowfish", 
     "mode"  => "ecb", 
    ), 
); 

say("= Mcrypt"); 
$handler = mcrypt_module_open($params['mcrypt']['cipher'], '', $params['mcrypt']['mode'], ''); 
$iv  = mcrypt_create_iv (mcrypt_enc_get_iv_size($handler), MCRYPT_RAND); 
$keysize = mcrypt_enc_get_key_size($handler); 
mcrypt_generic_init($handler,$key,"\0\0\0\0\0\0\0\0"); 
say(" Params:"); 
say(" - InitVector ".bin2hex($iv)." (bin2hex)"); 
say(" - Max keysize ".$keysize); 
say(" - Cipher  ".$params['mcrypt']['cipher']); 
say(" - Mode   ".$params['mcrypt']['mode']); 
say(""); 
say(" Encryption:"); 
$m_encrypted = mcrypt_generic($handler, $str); 
$m_decrypted = mdecrypt_generic($handler, $m_encrypted); 
say(" - Encrypted ".bin2hex($m_encrypted)." (bin2hex)"); 
say(" - Descrypted ".$m_decrypted); 
say(""); 


say("= Openssl"); 
say(" Params:"); 
say(" - InitVector not needed"); 
say(" - Max keysize ".openssl_cipher_iv_length($params['openssl']['cipher']."-".$params['openssl']['mode'])); 
say(" - Cipher  ".$params['openssl']['cipher']); 
say(" - Mode   ".$params['openssl']['mode']); 
say(""); 
say(" Encryption:"); 
$o_encrypted = openssl_encrypt($str,$params['openssl']['cipher']."-".$params['openssl']['mode'],$key,true); 
$o_decrypted = openssl_decrypt($o_encrypted,$params['openssl']['cipher']."-".$params['openssl']['mode'],$key,true); 
say(" - Encrypted ".bin2hex($o_encrypted)." (bin2hex)"); 
say(" - Descrypted ".$o_decrypted); 

E questo è il mio risultato:

= Begin raw encryption 
    Params: 
    - String to encrypt 'does it work' 
    - Key: anotherpass 

= Mcrypt 
    Params: 
    - InitVector 06a184909d7bf863 (bin2hex) 
    - Max keysize 56 
    - Cipher  blowfish 
    - Mode   ecb 

    Encryption: 
    - Encrypted 0e93dce9a6a88e343fe5f90d1307684c (bin2hex) 
    - Descrypted does it work 

= Openssl 
    Params: 
    - InitVector not needed 
    - Max keysize 0 
    - Cipher  BF 
    - Mode   ECB 

    Encryption: 
    - Encrypted 213460aade8f9c14d8d51947b8231439 (bin2hex) 
    - Descrypted does it work 

Forse qualche idea adesso?

Grazie!

+7

potrete sia necessario per eseguire uno script di migrazione che decifra i dati attuali con mcrypt e quindi crittografa nuovamente utilizzando OpenSSL, altrimenti si' È necessario implementare un metodo con cui si conoscono le funzioni di crittografia/decrittografia da utilizzare per ciascun elemento di dati e modificarle da mcrypt a openssl come richiesto quando si accede successivamente ad alcuni dati crittografati utilizzando mcrypt. – Jon

+1

Da quello che ho capito, mcrypt e open_ssl usano diversi metodi di derivazione delle chiavi e quindi Jon ha ragione, dovrai migrare per decifrare, quindi criptare o marcare i dati in modo che vengano migrati man mano che si accede. –

+0

Mi chiedo perché IB sia richiesto in modalità ECB. Vedi la descrizione della modalità ECB su http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation. – doptimusprime

risposta

8

Blowfish è il codice a blocchi. Richiede che i dati vengano riempiti prima della crittografia. OpenSSL utilizza PKCS # 7 e mcrypt utilizza PKCS # 5. Algoritmi di imbottitura diversi per i dati. La lunghezza minima del riempimento PKCS # 5 è 0, per PKCS # 7 è 1 (wikipedia). Date un'occhiata a questo esempio (ho i dati di input imbottiti manualmente mcrypt_encrypt() in PKCS # 7 stile):

<?php 

$key = "anotherpassword1"; 
$str = "does it work 12"; 

$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $key, $str."\1", MCRYPT_MODE_ECB); 
$dec = mcrypt_decrypt(MCRYPT_BLOWFISH, $key, $enc, MCRYPT_MODE_ECB); 
echo(bin2hex($enc).PHP_EOL); 
var_dump($dec); 

$enc = openssl_encrypt($str, 'bf-ecb', $key, true); 
$dec = openssl_decrypt($enc, 'bf-ecb', $key, true); 
echo(bin2hex($enc).PHP_EOL); 
var_dump($dec); 

?> 

E 'impossibile openssl_decrypt() i dati crittografati con mcrypt_encrypt(), a meno che non imbottitura manuale dei dati è stata fatta con È stato chiamato PKCS # 7 prima dello mcrypt_encrypt().

C'è un solo modo nel vostro caso: riattivare i dati.

PS: C'è un errore nella vostra fonte - Modalità BCE non utilizza affatto IV (wikipedia)

+1

Grazie, questo suggerimento mi ha aiutato a rendere Rijndael-128/AES-128 compatibile tra MCrypt e OpenSSL. Purtroppo però, non funziona per Blowfish - – Narf

+0

Si scopre che funziona per Blowfish, MA le dimensioni della chiave deve essere di almeno 16 byte (l'articolo di Wikipedia per Blowfish dice che supporta meno). – Narf

+0

È a causa del padding in PKCS # 7 – clover

-1

@clover è giusto che l'imbottitura di default per Blowfish è diverso tra il mcrypt e OpenSSL, ma è sbagliato che non può essere fatto.Se si utilizza l'opzione OPENSSL_ZERO_PADDING per il decrypt i due in realtà sono compatibili:

openssl_decrypt($data, 'bf-ecb', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING); 
+0

'OPENSSL_ZERO_PADDING' non aggiunge alcuna spaziatura, qualsiasi padding non standard dovrà essere aggiunto manualmente prima di crittografia e rimosso su decrittazione. Dalla documentazione [openssl_encrypt] (https://secure.php.net/manual/en/function.openssl-encrypt.php), forse stai usando una versione diversa. Dai commenti del doc: Quindi, OPENSSL_ZERO_PADDING disabilita il riempimento per il contesto, il che significa che dovrai applicare manualmente il tuo riempimento alla dimensione del blocco. Senza utilizzare OPENSSL_ZERO_PADDING, otterrai automaticamente il padding PKCS # 7. – zaph