Here are my requirements:
I need to encrypt a string in PHP using AES encryption (including random iv), Base64 encode it, and then encode by URL so that it can be passed as a URL parameter.
I am trying to get the same result in both PHP and Ruby, but I cannot get it to work.
Here is my PHP code:
function encryptData($data,$iv){ $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, ''); $iv_size = mcrypt_enc_get_iv_size($cipher); if (mcrypt_generic_init($cipher, 'g6zys8dlvvut6b1omxc5w15gnfad3jhb', $iv) != -1){ $cipherText = mcrypt_generic($cipher,$data ); mcrypt_generic_deinit($cipher); return $cipherText; } else { return false; } } $data = 'Mary had a little lamb'; $iv = '96b88a5f0b9efb43'; $crypted_base64 = base64_encode(encryptData($data, $iv));
Here is my Ruby code:
module AESCrypt def AESCrypt.encrypt(data, key, iv) aes = OpenSSL::Cipher::Cipher.new("aes-256-cbc") aes.encrypt aes.key = key aes.iv = iv aes.update(data) + aes.final end end plaintext = "Mary had a little lamb" iv = "96b88a5f0b9efb43" @crypted = AESCrypt::encrypt(plaintext, "g6zys8dlvvut6b1omxc5w15gnfad3jhb", iv) @crypted_base64 = Base64.encode64(@crypted) @crypted_base64_url = CGI.escape(@crypted_base64)
The concern is that both code samples create similar but not identical hashes. For example, the above code generates (base64 encoded, not URL encoded):
PHP: /aRCGgLBMOOAarjjtfTW2Qg2OtbPDLhx3KmgfgMzDJU=
Ruby: /aRCGgLBMOOAarjjtfTW2XIZhZ9VjBx8PdozxSL8IE0=
Can someone explain what I'm doing wrong here? Also, it is easier for me (since I'm usually Ruby, not PHP) to fix the Ruby code, not the PHP code. Therefore, if you want to provide a solution in Ruby that works well with PHP, I would really appreciate it.
Oh, and also, in production, iv will indeed be random, but for this example, I set it on an ongoing basis the same so that the result can be compared.
EDIT:
Thanks to Eugen Rieck's answer, I came to a solution. Ruby overlays blocks, but PHP does not, and you must do this manually. Change the PHP code to the following and you will get encrypted strings that can be decrypted higher than the Ruby code:
$iv = '96b88a5f0b9efb43'; $data = 'Mary had a little lamb'; function encryptData($data,$iv){ $key = 'g6zys8dlvvut6b1omxc5w15gnfad3jhb'; $padded_data = pkcs5_pad($data); $cryptogram = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $padded_data, MCRYPT_MODE_CBC, $iv); return $cryptogram; } function pkcs5_pad ($text, $blocksize){ $pad = $blocksize - (strlen($text) % $blocksize); return $text . str_repeat(chr($pad), $pad); }