首页 文章

弄清楚PHP的mcrypt创建的确切密钥

提问于
浏览
12

一个PHP应用程序I长度为256位,但只有160位 . 根据mcrypt_encrypt文档,密钥用\ 0填充以获得所需的大小(如果它太小) .

数据加密的密钥 . 如果它小于所需的密钥大小,则用'\ 0'填充 . 最好不要将ASCII字符串用于键 .

这似乎发生在line 1186 in mcrypt.c的开头附近,并在第1213行修改了密钥 .

所以我们说 $key = 'abcdefghijkm'; 太短了,但是当使用RIJNDAEL_256时,PHP 's implementation of mcrypt makes sure it'扩展为32个字符(或256位) . 最终的关键是什么样的?

我'm asking this because another application is being built that uses the same encrypted data, but is in another language. Perl to be exact and I'米使用Crypto::Rijndael . 对于给定的示例密钥,为了能够再次解密数据,我必须提供给 Crypto::Rijndael (或其他任何其他内容)的确切密钥是什么?

Update

使用Perl我可以生成一个键,其中\ 0填充为 pack('a32', 'my secret key'); (或 Z32 ), length() 将报告32并且 Crypt::Rijndael 模块接受该键 . 查看正在生成的PHP 's mcrypt this should be the key that'的源代码(\ 0填充),但它根本不会接受它 .

理论上在PHP pack('a32', 'my secret key'); 中应该得到与PHP 's mcrypt generates, but this isn' t相同的\ 0填充键 .

我非常接近只是用一把新密钥加密所有东西 . 这花费了太多时间 .

2 回答

  • 4

    问题是没有't the key'填充,它使用两种不同的块大小 . 在PHP中,使用 MCRYPT_RIJNDAEL_256 使用的块大小为... 256位 . 但是,在使用 Crypt::Rijndael 的perl中,他们注意到:

    blocksize Rijndael的块大小是16字节(128位),尽管算法实际上支持任何块大小,这是我们字节的任意倍数 . 但是,128位是AES指定的块大小,所以这就是我们所支持的 .

    所以没有关键允许在这些不同的算法之间进行转换 . 您可以在PHP中切换到128位:

    <?
    $key = "abcdefghijklmnopqrstuvwxyz";
    $data = "Meet me at 11 o'clock behind the monument.";
    $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_ECB, nil);
    echo bin2hex($crypttext) . "\n";
    // prints c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d
    ?>
    

    哪个Perl可以使用Crypt :: Rijndael解密而没有问题:

    use Crypt::Rijndael;
    $key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
    $crypttext = "c613d1804f52f535cb4740242270b1bcbf85151ce4c874848fd1fc2add06e0cc2d26b6403feef4a8df18f7dd7f8ac67d";
    $cipher = Crypt::Rijndael->new($key, Crypt::Rijndael::MODE_ECB());
    print $cipher->decrypt(pack('H*', $crypttext));
    # prints "Meet me at 11 o'clock behind the monument."
    

    或者您可以切换到支持更多块大小的其他Perl模块,例如Crypt::Rijndael_PP

    # Same PHP code except using MCRYPT_RIJNDAEL_256
    # prints f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c
    

    Perl的:

    use Crypt::Rijndael_PP ':all';
    $key = "abcdefghijklmnopqrstuvwxyz\0\0\0\0\0\0";
    $crypttext = "f38469ec9deaadbbf49bb25fd7fc8b76462ebfbcf149a667306c8d1c033232322ee5b83fa87d49e4e927437647dbf7193e6d734242d583157b492347a2b1514c";
    print rijndael_decrypt(unpack('H*', $key), MODE_ECB, pack('H*', $crypttext), 256, 256);
    # prints "Meet me at 11 o'clock behind the monument."
    
  • 12

    '\ 0'表示NULL,它的十六进制值为00!所以我测试了3个代码,他们返回了所有相同的:)

    • 让mcrypt_encrypt执行'\0'填充

    • 添加了PHP NULL值

    • 添加了PHP转换的0十六进制值

    码:

    function encryptThis($text,$key){
        $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv);
        return ($crypttext);
    }
    
    echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz"))."
    "; echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . NULL . NULL . NULL . NULL . NULL . NULL))."
    "; echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0) . hex2bin(0)))."
    "; ?>

相关问题