0

I have the following function in Ruby that decrypts a bit of data:

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

I'm trying to do the exact same thing in PHP, but I'm not sure what I'm doing wrong. Here's what I've got:

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

The output just ends up being garbage, not the string I'm looking for. Ideas?

And before we even start, switching it to MCRYPT_RIJNDAEL_256 doesn't seem help and just causes it to complain about the iv not being as long as the block size. I believe 128 is correct in this case since this site says that the 128/256 is an indication of the block size, not the key size.

Jeremy Logan
  • 47,151
  • 38
  • 123
  • 143
  • May I ask why you're doing this? Just for fun? Because you *really* shouldn't be writing your own encryption libraries for production use. They are ridiculously easy to screw up and extraordinarily hard to get right. – Eli Oct 27 '09 at 02:39
  • Uuh... I'm not, I'm using the built-ins. See the OpenSSL and the mcrypt references above. – Jeremy Logan Oct 27 '09 at 02:40
  • i don't see anything by just looking. Maybe try taking the decode of each of the iv, key, and text hexes and compare that directly to see if maybe something is wrong in there. Rijndael_256 should be the right cipher - could the IV be wrong, and ruby just isnt complaining? – Justin Oct 27 '09 at 02:53

2 Answers2

1

Personally I'm a little suspicious of the homebrewed hex_to_str function - why not just use pack('H*', $key)?

caf
  • 233,326
  • 40
  • 323
  • 462
  • Because I didn't know it was there! Thanks. However, using it gives me the same results as my `hex_to_str()` function. – Jeremy Logan Oct 27 '09 at 03:03
0

It turns out that it was working fine, it's just that my test data was bad. The two changes I made were using pack() (at caf's suggestion) and dropping the padding characters from the end.

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"
    );
}
Jeremy Logan
  • 47,151
  • 38
  • 123
  • 143