dimensione della chiave non corretta quando il porting crittografia Crypto ++ AES per mcrypt di PHP

StackOverflow https://stackoverflow.com/questions/4052594

Domanda

In precedenza sono riuscito a porta po 'di codice C ++ cryptopp Rijndael_128 CBC per MCrypt PHP, ma ora sto avendo problemi con la modalità CFB. I risultati C ++ e PHP non corrispondono (bene le prime partite di byte, ma questo potrebbe essere una coincidenza, tutto il resto non lo fa). Con alcuni di diagnostica, sembra mcrypt di PHP non è l'impostazione correttamente la lunghezza della chiave?

Ecco il C ++ (diagnostica e articoli vari rimosse per semplicità):

CFB_Mode<AES>::Encryption encryptor(g_encrypt_key, AES::DEFAULT_KEYLENGTH, g_encrypt_iv);

StringSource ss( sInput.c_str(), true, 
        new StreamTransformationFilter( encryptor, 
            new HexEncoder( new StringSink( sEncryptedOut ) )
        ));

Ed ecco il PHP:

$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CFB, '')
mcrypt_generic_init($cipher, $g_encrypt_key, $g_encrypt_iv);

$sEncryptedOutput = mcrypt_generic( $cipher, $sInput);
mcrypt_generic_deinit($cipher);
mcrypt_module_close($cipher);

g_encrypt_key e g_encrypt_iv sono entrambi 16 byte lungo, ei byte corrispondono per la versioni di PHP C ++ e. Per la versione di PHP è una stringa binaria costruito dai byte (sì controllato essi sono identici).

Ho aggiunto le chiamate alla versione di PHP per la dimensione del blocco di controllo di $cipher, dimensione della chiave, ecc La dimensione del blocco e la dimensione iv sono entrambi 16; dimensioni delle chiavi supportati sono riportati come 16, 24, e 32 -. tutto come previsto

Dove penso che il problema è, è che la dimensione della chiave sono stati segnalati come 32 byte. Guardando la documentazione mcrypt, l'unico modo di impostare la dimensione della chiave è di fornire una chiave delle dimensioni richieste. Ma sto passando una chiave di 16 byte! Allora perché è segnalando la presenza di una chiave di 32 byte? Se la modalità CFB deve utilizzare una chiave di 32 byte, allora perché cryptopp accetta come bene? Qual'è la soluzione? Posso forzare PHP per utilizzare la chiave di 16 byte che è stato fornito? O c'è un parametro che mi manca, che è inadempiente ad una diversa impostazione in cryptopp che in MCrypt?

Sto usando la modalità CFB perché voglio ridurre al minimo la lunghezza dei dati crittografati risultanti. I pochi byte che padding sarebbe introdurre, fanno la materia in questa applicazione.

ho bisogno di essere in grado di cifrare / decifrare in C ++, ma crittografare solo in PHP. AES è probabilmente eccessivo per la mia domanda -. La necessità minimo che è "un buon rimescolamento dei byte" in modo che la funzione dei singoli byte nei dati non sono evidenti

È stato utile?

Soluzione

E 'stato un po', ma ho avuto alcuni problemi simili con mcrypt e openSSL utilizzando CFB un paio di anni fa. Alla fine, ho scoperto mcrypt usato un formato differente catena risposte predefinite che openssl in modalità CFB. Vale a dire, ritengo un openSSL AES128 in CFB utilizzata una dimensione del blocco e feedback dimensione di 128 bit, mentre mcrypt utilizzata una dimensione di blocco di 128bits e una dimensione valutazioni di 8 bit. Non ho modo di confermare questo, era solo speculazione, al momento in base a leggere alcuni post vecchi del forum. A prescindere dalla verità di quella teoria, non ero l'unica persona o il primo ad avere questo particolare problema.

La soluzione per me è stato quello di utilizzare nofb come te stesso. Secondo la PHP mcrypt riferimento libreria forze MCRYPT_MODE_NOFB le valutazioni catena a parità di dimensione dei blocchi dell'algoritmo, in questo caso un blocco 128 bit / risposte per AES128 (Rijndael), che corrisponde a quanto il manpage per il modulo mcrypt stati circa nofb. Questo è buono come tutto ho trovato detto risposte nofb è sincrono alla dimensione del blocco. Così, sia mcrypt e OpenSSL in nofb ora erano 128 Chiave bit / iv / blocco / dimensioni feedback per AES128 e tutto funzionava bene.

Per quanto riguarda PHP keysizes segnalazione 256bit (32 byte), la funzione che restituisce la dimensione attuale chiave di cifratura-algoritmo in realtà restituisce la dimensione massima della chiave, che non è chiaramente indicato nella documentazione. Lo so perché la mia piccola classe che uso per tutto il tempo ora per vari progetti funziona perfettamente bene con openSSL e altre librerie AES a CBC o nofb. Questo non sarebbe il caso se è stato mcrypt imbottitura la mia chiave a 128 bit (16 caratteri) con l'aggiunta di 128bits di stringa nulla, o qualsiasi altra cosa, e non sarebbe tecnicamente corretto in ogni caso.

Non proprio una buona risposta, ma il migliore che ho ottenuto sulla base di un'incursione molto amatoriale in crittografia diversi anni fa.

Altri suggerimenti

Partenza phpseclib:

http://phpseclib.sourceforge.net/

È possibile impostare la dimensione della chiave e dimensione dei blocchi per quello che vuoi.

ad es. $ AES> setKeyLength (128) o $ AES> setKeyLength (256);

Ho avuto questo problema - paio di punti. Per impostazione predefinita, la modalità di PHP Rijndael imposta il ciclo di feedback a 8bits - di essere AES è deve essere la stessa lunghezza del IV / chiave

.

È possibile farlo utilizzando la modalità 'NCFB' invece di 'cfb' o MCRYPT_MODE_CFB.

I dettagli completi di scrittura aes_cfb_128 PHP compatibili sono a questa domanda di sicurezza StackExchange: aes CFB 128 decifratura / codifica problema tra Erlang e PHP . Il corto di esso è (da Tom Leek):

  

... sia per la CFB e OFB (che sono distinti tra loro e non possono essere usati in modo intercambiabile), si deve preoccuparsi di "lunghezza feedback" che non è necessariamente documentata con elevata chiarezza nelle varie librerie crittografiche. Sia la crittografia e la decrittografia devono utilizzare la stessa lunghezza di feedback di interoperare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top