Figuring out the exact key created by PHP's mcrypt

后端 未结 2 1651
情深已故
情深已故 2021-01-11 12:53

A PHP application I\'m maintaining uses Rijndael_256 with EBC_MODE encryption with mcrypt. Fun has it that the key isn\'t 256 bits long, but only 160. According to the mcryp

相关标签:
2条回答
  • 2021-01-11 13:41

    '\0' means NULL, the hex value of it is 00 ! So i tested 3 codes, and they returned all the same :)

    1. Let mcrypt_encrypt do the '\0' padding
    2. Added with PHP NULL values
    3. Added with PHP converted 0 hex values

    Code:

    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"))."<br/>";
    
    echo bin2hex(encryptThis("Meet me at 11 o'clock behind the monument.", "abcdefghijklmnopqrstuvwxyz" . NULL . NULL . NULL . NULL . NULL . NULL))."<br/>";
    
    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)))."<br/>";
    
    ?>
    
    0 讨论(0)
  • 2021-01-11 13:46

    The issue isn't the key's padding, it's that you're using two different block sizes. In PHP, using MCRYPT_RIJNDAEL_256 uses a block size of... 256 bits. However, in perl using Crypt::Rijndael, they note:

    blocksize
    The blocksize for Rijndael is 16 bytes (128 bits), although the algorithm actually supports any blocksize that is any multiple of our bytes. 128 bits, is however, the AES-specified block size, so this is all we support.

    So there's no key that will allow for conversion between those different algorithms. You can either switch to 128 bits in PHP:

    <?
    $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
    ?>
    

    Which Perl can decrypt without a problem using 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."
    

    Or you can switch to a different Perl module that supports more block sizes, e.g., 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."
    
    0 讨论(0)
提交回复
热议问题