Преобразование функции расшифровки Ruby AES256 в PHP

У меня есть следующая функция в Ruby, которая расшифровывает бит данных:

def decrypt(key, iv, cipher_hex)
    cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')

    cipher.decrypt
    cipher.key = key.gsub(/(..)/){|h| h.hex.chr}
    cipher.iv = iv.gsub(/(..)/){|h| h.hex.chr}

    decrypted_data = cipher.update(cipher_hex.gsub(/(..)/){|h| h.hex.chr})
    decrypted_data << cipher.final

    return decrypted_data
end

Я пытаюсь сделать то же самое в PHP, но я не уверен, что я делаю неправильно. Вот что у меня есть:

function decrypt_data($key, $iv, $cipher_hex) {
    return mcrypt_decrypt(
        MCRYPT_RIJNDAEL_128, 
        hex_to_str($key), 
        hex_to_str($cipher_hex), 
        MCRYPT_MODE_CBC, 
        hex_to_str($iv)
    );
}

function hex_to_str($hex_str) {
    preg_match_all('/(..)/', $hex_str, $matches);

    $to_return = '';
    foreach ($matches[1] as $val)
        $to_return .= chr(hexdec($val));
    return $to_return;
}

Вывод просто оказывается мусором, а не строкой, которую я ищу. Идеи?

И еще до того, как мы начнем, переключение на MCRYPT_RIJNDAEL_256 не кажется полезным и просто заставляет его жаловаться на то, что iv не такой длинный, как размер блока. Я считаю, что 128 в данном случае является правильным, так как этот сайт говорит, что 128/256 указание размера блока, а не размера ключа.


person Jeremy Logan    schedule 27.10.2009    source источник
comment
Могу я спросить, почему вы это делаете? Просто для удовольствия? Потому что вам на самом деле не следует писать свои собственные библиотеки шифрования для производственного использования. Их смехотворно легко испортить и чрезвычайно трудно исправить.   -  person Eli    schedule 27.10.2009
comment
Эээ... нет, я использую встроенные модули. См. ссылки на OpenSSL и mcrypt выше.   -  person Jeremy Logan    schedule 27.10.2009
comment
я ничего не вижу, просто глядя. Может быть, попробуйте декодировать каждый из шестнадцатеричных символов iv, key и text и сравнить их напрямую, чтобы увидеть, может быть, что-то не так. Rijndael_256 должен быть правильным шифром - может ли IV быть неправильным, а рубин просто не жалуется?   -  person Justin    schedule 27.10.2009


Ответы (2)


Лично я немного подозрительно отношусь к доморощенной функции hex_to_str — почему бы просто не использовать pack('H*', $key)?

person caf    schedule 27.10.2009
comment
Потому что я не знал, что это было там! Спасибо. Однако ее использование дает мне те же результаты, что и моя функция hex_to_str(). - person Jeremy Logan; 27.10.2009

Оказывается, он работал нормально, просто мои тестовые данные были плохими. Два изменения, которые я сделал, заключались в использовании pack() (по предложению caf) и удалении символов заполнения с конца.

function decrypt_data($key, $iv, $cipher_hex) {
    return rtrim(
        mcrypt_decrypt(
            MCRYPT_RIJNDAEL_128, 
            pack('H*', $key), 
            pack('H*', $cipher_hex), 
            MCRYPT_MODE_CBC, 
            pack('H*', $iv)
        ), 
        "\x00..\x1F"
    );
}
person Jeremy Logan    schedule 27.10.2009
comment
будьте осторожны - у меня были проблемы с пакетом ('H *') и откусыванием символов заполнения, но, возможно, это только я. - person Justin; 28.10.2009
comment
Спасибо за внимание, Джастин. Кажется работает нормально :) - person Jeremy Logan; 28.10.2009