php
  • ruby
  • openssl
  • aes
  • rijndael
  • 2013-08-22 6 views 0 likes 
    0

    Я хочу использовать rijndael aes128 для шифрования в рубине. У меня есть этот код:Rijndael Расшифровка шифрования AES-128 в Ruby

    cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc") 
    cipher.encrypt 
    cipher.key = 'abcdefabcdef' 
    cipher.iv = '0000000000000000' 
    encrypted = cipher.update('2~1~000024~0910~20130723092446~T~00002000~USD~F~375019001012120~0~0~00000000000~') 
    encrypted << cipher.final 
    

    который не работает. Но использование этой PHP функции:

    <?php 
    function hex2bin($hex_string) 
        { 
        return pack('H*', $hex_string); 
        } 
    $data_to_encrypt = '2~1~000024~0910~20130723092446~T~00002000~USD~F~375019001012120~0~0~00000000000~'; 
        $key = 'abcdefabcdef'; 
        $iv = '0000000000000000'; 
        $key = hex2bin($key); 
        $iv = hex2bin($iv); 
        $data_encrypted = bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data_to_encrypt, MCRYPT_MODE_CBC, $iv)); 
        echo "Data encrypted: ".strtoupper($data_encrypted)."<br/>"; echo "Length: ".strlen($data_encrypted)."<br/>"; 
        ?> 
    

    я получил желаемый результат:

    0D5835AFEBEE04C6DC2421538DB7C38A1283970EB31F21A47D2E3CC623D29EF0461279C7ACF93B031BE2B69CE45C9339554957F29EF609F019EEC975983A03B537622D7E0F196BE148F1C7CBB88E602A 
    

    Как я могу получить мой рубин код, чтобы произвести тот же результат?

    +0

    Есть так много вещей, которые могут пойти не так, и поскольку PHP и Ruby являются врагами, как вы ожидаете, что люди проведут проверку вашей проблемы? Попробуйте просмотреть оба руководства или проверить некоторые вопросы на SO (на правой панели), возможно [это] (http://stackoverflow.com/questions/1862710/how-to-make-ruby-aes-256-cbc-and -php-mcrypt-rijndael-128-play-well-together), вы дадите вам некоторое представление о том, что может быть неправильным ... – HamZa

    ответ

    4

    Проблема заключается в том, что Mcrypt не дополняя последний блок, в то время как в Ruby OpenSSL связывание использует OpenSSL методы заполнените по умолчанию, который является PKCS обивки. Я не могу улучшить описание из документации OpenSSL:

    Заполнение дополнений PKCS путем добавления n байтов заполнения значения n, чтобы общая длина данных была кратной размеру блока. Заполнение всегда добавляется, поэтому, если данные уже кратно размеру блока n, будет равен размеру блока. Например, если размер блока составляет 8 и 11 байтов, то будет добавлено 5 байтов заполнения значения 5. Вам нужно будет вручную добавить правильное заполнение в конец открытого текста в PHP до шифрования. Для этого передайте свой $ cleartext через эту функцию pkcs5_pad на стороне PHP, прежде чем вы ее зашифруете (передавая 16 в качестве блока).

    function pkcs5_pad ($text, $blocksize) 
    { 
        $pad = $blocksize - (strlen($text) % $blocksize); 
        return $text . str_repeat(chr($pad), $pad); 
    } 
    

    Если вы идете в другую сторону (зашифровать в Рубине и дешифрования с Mcrypt), вам придется сдирать байты заполнения после дешифрования.

    Боковое примечание: причина, по которой вам нужно добавить отступы, даже если текст текста уже кратен блокам (целый блок отступов), заключается в том, что при расшифровке вы знаете, что последний байт последнего блока всегда добавляется количество дополнений. В противном случае вы не могли бы разделить различие между открытым текстом с единственным байтом заполнения и открытым текстом без байтов заполнения, которые только что закончились с значением 0x01.

    4
    require 'openssl' 
    
    cleartext = '2~1~000024~0910~20130723092446~T~00002000~USD~F~375019001012120~0~0~00000000000~' 
    key = 'abcdefabcdef' 
    iv = '0000000000000000' 
    
    cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc") 
    cipher.encrypt 
    cipher.padding = 0 
    cipher.key = [key].pack('H*') 
    cipher.iv = [iv].pack('H*') 
    encrypted = cipher.update(cleartext) 
    encrypted << cipher.final 
    puts encrypted.unpack('H*').first.upcase 
    

    Выход:

    0D5835AFEBEE04C6DC2421538DB7C38A1283970EB31F21A47D2E3CC623D29EF0461279C7ACF93B031BE2B69CE45C9339554957F29EF609F019EEC975983A03B537622D7E0F196BE148F1C7CBB88E602A 
    
    +0

    это мой полный код, который дает то же самое, что я написал выше. ? php function hex2bin ($ hex_string) {return pack ('H *', $ hex_string); } $ data_to_encrypt = '2 ~ 1 ~ 000024 ~ 0910 ~ 20130723092446 ~ T ~ 00002000 ~ USD ~ F ~ 375019001012120 ~ 0 ~ 0 ~ 00000000000 ~'; $ key = 'abcdefabcdef'; $ iv = '0000000000000000'; $ key = hex2bin ($ key); $ iv = hex2bin ($ iv); $ data_encrypted = bin2hex (mcrypt_encrypt (MCRYPT_RIJNDAEL_128, $ key, $ data_to_encrypt, MCRYPT_MODE_CBC, $ iv)); echo «Шифрование данных:» .strtoupper ($ data_encrypted). «
    »; echo "Length:" .strlen ($ data_encrypted). "
    "; ?> –

    +0

    Этот код очень отличается от того, который вы опубликовали выше! Как мы должны угадывать весь окружающий код? Когда вы публикуете много кода, просто отредактируйте свой ответ, вместо того, чтобы помещать его в комментарий. –

    +0

    Ваш код выдает предупреждение: 'mcrypt_encrypt(): параметр IV должен быть до тех пор, пока он не блокируется. И ключ, и IV должны быть вдвое длиннее! –

     Смежные вопросы

    • Нет связанных вопросов^_^