1

I am new to encryption. I want to encode a string with AES 128bit encryption. I can do this in PHP:

$key = 'Hello';
$plain = 'Hello Hello Hello Hello';

$cipher = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plain, MCRYPT_MODE_CBC);

echo base64_encode($cipher);

This outputs:

bzXdTNochlsQwpR9hzSSS6ihG+MYIZIDZZlF85pIXlQ=

I tried the same with openssl command line:

openssl enc -aes-128-cbc -a -nosalt -in plain.txt -out encrypted.enc -pass pass:Hello

And the string saved in encrypted.enc is:

5apwiN8MdAuJ9nEW82XMyR0H3VKpI/vWc7xV2iVjCTE=

Why is it different?

The reason why I am trying to get the same output with both PHP and command line openssl is because I will have two separate web services communicating together. One service will have PHP available so I can use that but the other one will not be using PHP so I will probably have to use openssl in command line.

2
  • MCRYPT_RIJNDAEL_128 might not be the same as aes-128 probably? Also -pass pass:Hello does not look like to set the same password. And I think good encryption does not look always the same even the plain and the password are the same. It is more important if you can decrypt what you have crypted with the other one and vice-versa. Commented Aug 5, 2012 at 18:50
  • RIJNDAEL is AES -- the only difference is in block size but 128 makes it the same. While pass:Hello does specify the password Hello for enc, openssl needs to derive a key, while mcrypt uses a key not the password. Finally, good encryption as you say might be different depending on the Initialization Vector but no good algorithm uses a random from inside the algo. Same starting values, same results. He has many problems with the starting values: the plain is padded differently, the key is derived differently. Commented Aug 5, 2012 at 19:33

1 Answer 1

1

You mixed up password and key. Add a -p to your openssl command line to see the actual key used and observe http://php.net/manual/en/function.mcrypt-encrypt.php string mcrypt_encrypt ( string $cipher , string $key <= key! Not password.

Edit:

You also have problems with padding. Now making your plain text 48 chars (3*128 bit=3*16 bytes) long:

$plain = 'Hello Hello Hello Hellox';
$plain .= $plain;
function hexstr($hexstr) {
  // return pack('H*', $hexstr); also works but it's much harder to understand.
  $return = '';
  for ($i = 0; $i < strlen($hexstr); $i+=2) {
    $return .= chr(hexdec($hexstr[$i] . $hexstr[$i+1]));
  }
  return $return;
}
$cipher = @mcrypt_encrypt(MCRYPT_RIJNDAEL_128, hexstr('25c506a9e4a0b3100d2d86b49b83cf9a'), $plain, MCRYPT_MODE_CBC, hexstr('00000000000000000000000000000000'));

echo base64_encode($cipher);
echo "\n";

And

openssl enc -aes-128-cbc -a -iv 0  -nosalt -in plain.txt  -K 25c506a9e4a0b3100d2d86b49b83cf9a -nopad

results the same:

EZjBup0sfRAkIZ2/IQ3bKHWXHG4qBVv4uyW0PnxJJWvWHanNgE1QyBHMpWoZqejR
Sign up to request clarification or add additional context in comments.

7 Comments

Is there a way I can set what key to use with OpenSSL?
Edited the reply with sample PHP code that returns the same as an OpenSSL command. See how I used -K to ensure the sameness of key in OpenSSL and PHP. Also, use a more solid iv than 0, mcrypt has IV generating functions.
Thank you. What is hexstr() for?
Well, how do you plan to convert 25c506a9e4a0b3100d2d86b49b83cf9a into the binary string PHP expects? I bet there's a pack command for that but I can never remember the pack magic. Edit: OK, editing the answer.
Don't you need salts and padding? Just using no salt or IV makes the code insecure. No padding means only use plain texts with with a size equal to N x block size.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.