1

I have been trying to encrypt a string in PHP and Ruby using the same key and iv but I always got different results.

Below is the PHP Code

$data = "This string needs to be encrypted";

$key = "1234567887654321abcdefghabcdefgh";

$iv = "1234567887654321abcdefghabcdefgh";

echo $encrypted_data = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CBC, $iv);

Below is the Ruby Code

data = "This string needs to be encrypted"

key = "1234567887654321abcdefghabcdefgh"

iv = "1234567887654321abcdefghabcdefgh"

aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
aes.encrypt
aes.key = key
aes.iv = iv
encrypted_data = aes.update(data) + aes.final

Could somebody please help me get the same encrypted data in PHP and Ruby? I encrypted some data in PHP and then decrypted in Ruby but didn't get the data back. So I think the issue is PHP and Ruby encryption and decryption mechanism work differently. Please correct me if I am wrong. Thanks

user812120
  • 585
  • 1
  • 10
  • 21
  • possible duplicate of [Ruby on Rails Decryption](http://stackoverflow.com/questions/10104964/ruby-on-rails-decryption) by the same user. – Andrew Marshall Apr 17 '12 at 13:30
  • Please follow this answer, this is helpful too: https://stackoverflow.com/questions/21485437/encrypting-in-php-mcrypt-decrypting-in-ruby-opensslcipher – Nikhil Pingle Feb 27 '15 at 20:51

1 Answers1

3
  1. Don't hard code IV's , it is insecure. IVs must be random but can be public , so just use
    mcrypt_create_iv and prepend it to the front of the ciphtertext and then extract it before decrypting

  2. You likely have three problems

    1. MCRYPT_RIJNDAEL_256 is nott AES. AES is a specific version RIJNDAEL that was standardized with a 128 bit block size and either 128 or 256 bit keys. MCRYPT_RIJNDAEL_256 is RIJNDAEL with a 256 bit block size. You want to use MCRYPT_RIJNDAEL_128 which is actually AES. For php, key length is just determined by the length of the key. So just give it a 256 bit ( 32 character) key and you will be fine. Note block size does not effect security really, so don't worry about the deference and just use AES with a 256 bit key: its good enough for the NSA and top secret data.
    2. Padding. AES only takes fixed 128 bit chunks, so you must pad out the text to be a multiple of that size. PHP doesn't really bad and i believe SSL uses pkcs7 padding. Note that even with different padding schemes, for most of them the start of the cipher text should the the same there just may be garbage at the end.

    3. String encoding. AES is defined with bit inputs, in c typically this is a byte array. Ruby and PHP use strings. I'd be willing to bet your string encodings are different.

Community
  • 1
  • 1
imichaelmiers
  • 3,449
  • 2
  • 19
  • 25
  • Many thanks for your prompt response. I am new to this encryption world. Could you please elaborate on it? I am really stuck on this stuff for three days. – user812120 Apr 16 '12 at 21:01
  • Make sure you actually are feeding the same bits to ruby and PHP for your key and IV. If possible I'd do this with a byte array or if you can get bytes from hex method or something. I don't use PHP much these days and Don't know ruby. Second point though, if you are just trying to send this securely between servers, why not use SSL? – imichaelmiers Apr 16 '12 at 21:04
  • I am still getting different results :( – user812120 Apr 17 '12 at 11:27
  • Is there a Ruby equivalent of MCRYPT_RIJNDAEL_256? If I use MCRYPT_RIJNDAEL_256 in PHP and AES-256-CBC in Ruby to encrypt the same data using the same key (32 characters) and iv (32 characters) and then base64 encode the encrypted data, I always get different results. However, if I use MCRYPT_RIJNDAEL_128 in php and AES-256-CBC in Ruby using a key (32 characters) and iv (16 characters) and then base64 encode the encrypted data, I get the same results. – user812120 Apr 17 '12 at 13:26
  • 1
    PHP rijndael_256 is not AES with a 256 bit key, its rijndael with a 256 bit block size. You want to use MCRYPT_RIJNDAEL_128 with a 256 bit (32 character) key. WHile they might be an equivalent to MCRYPT_RIJNDAEL_256 in ruby, you don't want it. You want to use AES since thats the standard. Also block size does not really effect security, unlike key size – imichaelmiers Apr 18 '12 at 00:30