Pergunta

Anteriormente eu consegui porta alguns C++ CryptoPP Rijndael_128 CBC código para MCrypt PHP, mas agora eu estou tendo problemas com o modo CFB.O C++ e PHP resultados não coincidem (bem, o primeiro byte corresponde, mas isso poderia ser uma coincidência, tudo o resto não).Com alguns diagnósticos, parece que o PHP mcrypt não é definir o comprimento da chave corretamente?

Aqui está o C++ (diagnóstico e diversos removido por simplicidade):

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 ) )
        ));

E aqui está o 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 são ambos de 16 bytes e bytes correspondência para o C++ e PHP versões.Para a versão de PHP é uma string binária construída a partir de bytes (sim, eu tenho verificado estes são idênticos).

Eu adicionei chamadas para o PHP versão para verificar $cipher's tamanho do bloco, tamanho da chave, etc.O tamanho do bloco e iv, tamanho 16;suportados tamanhos de chave são relatados como 16, 24 e 32, tudo como esperado.

Onde eu acho que o problema é que o algoritmo está sendo relatado como um de 32 bytes.Olhando para o mcrypt docs, a única maneira de definir o algoritmo é através do fornecimento de uma chave do tamanho necessário.Mas estou passando uma chave de 16 bytes!Então, porque é relatar a presença de uma versão de 32 bytes de chave?Se CFB modo deve usar uma versão de 32 bytes de chave e, em seguida, por que CryptoPP aceitá-lo como tá?Qual é a solução?Posso forçar o PHP para usar a chave de 16 bytes que foi fornecido?Ou existe um parâmetro que eu estou ausente que é padrão para uma configuração diferente no CryptoPP que em MCrypt?

Eu estou usando o modo CFB porque eu quero minimizar o comprimento dos dados criptografados resultantes.A poucos bytes de preenchimento introduziria, não importa nesse aplicativo.

Eu preciso ser capaz de criptografar/descriptografar em C++, mas apenas criptografar em PHP.AES é, sem dúvida, um exagero para meu aplicativo - o mínimo que eu preciso é "um bom misturar os bytes" para que a função de bytes individuais em que os dados não são óbvias.

Foi útil?

Solução

Já faz algum tempo, mas tive alguns problemas semelhantes com McRypt e OpenSSL usando o CFB há alguns anos. No final, descobri que o MCRYPT usava um tamanho de cadeia de feedback padrão diferente do OpenSSL no modo CFB. Ou seja, acredito que um OpenSSL AES128 no CFB usou um tamanho de bloco e tamanho de feedback de 128 bits, enquanto McRypt usou um tamanho de bloco de 128 bits e um tamanho de feedback de 8 bits. Não tenho como confirmar isso, foi apenas especulação na época com base na leitura de algumas postagens antigas do fórum. Independentemente da verdade dessa teoria, eu não era a única pessoa ou primeiro a ter essa questão em particular.

A solução para mim era usar o NOFB como você. De acordo com Referência da biblioteca PHP McRypt MCRYPT_MODE_NOFB força a cadeia de feedback a igualar o tamanho do bloco do algoritmo, neste caso um bloco/feedback de 128 bits para o AES128 (Rijndael), que corresponde ao que o MANPAGE Para o módulo McRypt, declara sobre Nofb. Isso é bom, pois tudo o que achei que o feedback nofb é síncrono com o tamanho do bloco. Assim, o MCRYPT e o OpenSSL no NOFB agora eram de 128 bits -chave/iv/bloqueio/feedback para o AES128 e tudo funcionou bem.

No que diz respeito ao relatório de PHP de 256 bits (32 bytes), a função que retorna o tamanho da chave atual do algoritmo cifra realmente retorna o tamanho máximo da chave, que não está claramente declarado na documentação. Eu sei disso porque minha pequena classe que uso o tempo todo agora para vários projetos funciona perfeitamente bem com o OpenSSL e quaisquer outras bibliotecas da AES no CBC ou NOFB. Não seria esse o caso se McRypt estivesse preenchendo minha chave de 128 bits (16 char) com 128 bits adicionais de corda nula, ou o que quer que seja, e não estaria tecnicamente correto de qualquer maneira.

Não é realmente uma boa resposta, mas o melhor que tive baseado em uma incursão muito amadora na criptografia há vários anos.

Outras dicas

Confira phpseclib:

http://phpseclib.sourceforge.net/

Você pode definir o tamanho da chave e o tamanho do bloqueio para o que quiser.

por exemplo. $ aes-> setKeyLength (128) ou $ aes-> setKeyLength (256);

Eu tive esse problema - par de pontos.Por padrão o PHP Rijndael modo define o ciclo de feedback para 8bits - para ser AES é necessário ser o mesmo comprimento que o IV/Chave.

Você pode fazer isso usando o modo 'ncfb" em vez de " cfb " ou MCRYPT_MODE_CFB.

Detalhes completos da escrita aes_cfb_128 compatível com o PHP estão em Segurança Stackexchange pergunta: aes cfb 128 descriptografia /problema de criptografia entre Erlang e PHP.O curto do que é (de Tom Alho-porro):

...para tanto CFB e OFB (que são distintos uns dos outros e não podem ser usados de forma intercambiável), você terá de se preocupar com o "feedback comprimento" o que não é, necessariamente, documentado com grande clareza em várias bibliotecas de criptografia.A criptografia e a descriptografia deve usar a mesma resposta de comprimento para interoperar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top