1

I'm trying to learn how to perform a simple encrypt/decrypt between a Windows 64 machine (my PC) and PHP running on a Linux web server using openSSL.

On my Windows machine, I've installed OpenSSL v1.0.2k for Win64 and I'm using the following command to create an encrypted string using a simple password and a simple key located in secretkey.txt.

enc -aes-256-cbc -A -base64 -nopad -nosalt -pass pass:hello -in secretkey.txt

When I run the command above, I get the following string:

3WE7cuBFhuLCn3/ZBnUrBn68nn3tVn0NKKz63B3uvoc=

Using the string above, I would expect PHP on my Linux web server to be able to decrypt it like this:

 $encrypted = '3WE7cuBFhuLCn3/ZBnUrBn68nn3tVn0NKKz63B3uvoc=';
 $enc = 'aes-256-cbc';
 $password = 'hello';
 $key = openssl_decrypt($encrypted, $enc, $password, OPENSSL_ZERO_PADDING);
 echo $key .' should equal this-1234-is-4567-my-8910-secret';

But, instead I get this:

9(j���T]��$�W�Ma��S��zz�>.( should equal this-1234-is-4567-my-8910-secret

I've reviewed the following sites and tried multiple versions, but I can't get it to decrypt properly:

Open SSL Enc
Open SSL Command Line
PHP Decrypt

Marc
  • 1,470
  • 2
  • 16
  • 25
  • not a duplicate. the question is about trying to encrypt from the command line (windows) and decrypt using php. the recommended solution is all about encrypting and decrypting all within PHP. – Marc Feb 16 '17 at 14:54
  • Are you base64 decoding the openssl output in your PHP code? – President James K. Polk Feb 16 '17 at 21:03
  • Zero padding is a poor idea, in general PKCS#7 (née PKCS#5) padding is used. Zero padding will not allow binary data to be encrypted that happens to end with a zero (0x00) byte. – zaph Feb 17 '17 at 15:29

1 Answers1

1

AES requires a key to work. This is a sequence of bytes of exactly the exact length (32 in the case of AES-256). You can’t directly use a password (unless the bytes that make up the password happen to be the right length).

Furthermore, CBC mode requires an initialization vector (IV) of 16 bytes.

The OpenSSL enc command derives the key and the IV to use from the password provided using an internal function EVP_BytesToKey. In order to decrypt a file that has been encrypted with enc you need to reproduce this function. The details of the algorithm are in the docs. In PHP, it might look like this:

$password = 'hello';

$bytes = "";
$last = "";

// 32 bytes key + 16 bytes IV = 48 bytes.
while(strlen($bytes) < 48) {
    $last = md5($last . $password, true);
    $bytes.= $last;
}

// First 32 bytes are the key, next 16 are the IV.
$key = substr($bytes, 0, 32);
$iv = substr($bytes, 32, 16);

You can then use these values in the openssl_decrypt command:

$enc = 'aes-256-cbc';
$result = openssl_decrypt($encrypted, $enc, $key, OPENSSL_ZERO_PADDING, $iv);
matt
  • 78,533
  • 8
  • 163
  • 197