user812120
user812120

Reputation: 585

PHP (mcrypt_encrypt) Ruby (AES-256-CBC) Encryption Different Results

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

Upvotes: 1

Views: 3242

Answers (1)

imichaelmiers
imichaelmiers

Reputation: 3509

  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.

Upvotes: 3

Related Questions