Reputation: 1578
According to the documentation of OpenSSL
( https://www.openssl.org/docs/apps/enc.html#OPTIONS ) they expect a hex-digit
value for key
and iv
; does that mean only numbers? or will a md5
hash do? (Because a md5
doesn't seem reversible)
key
and iv
because $password
in the PHP
function openssl_encrypt
is actually the key. (Almost) straight from PHP
comments ( http://php.net/manual/en/function.openssl-encrypt.php )
function strtohex($x)
{
$s='';
foreach (str_split($x) as $c) $s.=sprintf("%02X",ord($c));
return($s);
}
$source = 'It works !';
$iv = substr( md5( "123sdfsdf4567812345678" ), 0, 16 );
$pass = '1234567812345678';
$method = 'aes-256-cbc';
echo "\niv in hex to use: ".$iv;
echo "\nkey in hex to use: ".strtohex($pass);
echo "\n";
file_put_contents ('./file.encrypted',openssl_encrypt ($source, $method, $pass, true, $iv));
$exec = "openssl enc -".$method." -d -in file.encrypted -nosalt -nopad -K ".strtohex($pass)." -iv ".$iv;
echo 'executing: '.$exec."\n\n";
echo exec ($exec);
echo "\n";
Upvotes: 4
Views: 11033
Reputation: 21883
It took me some time to work with the openssl documentation. Finally I had the solution to return encoded and decoded as ASCII text with base64_encode():
//Return encrypted string
public function stringEncrypt ($plainText, $cryptKey = '7R7zX2Urc7qvjhkr') {
$length = 8;
$cstrong = true;
$cipher = 'aes-128-cbc';
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
$ciphertext_raw = openssl_encrypt(
$plainText, $cipher, $cryptKey, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $cryptKey, $as_binary=true);
$encodedText = base64_encode( $iv.$hmac.$ciphertext_raw );
}
return $encodedText;
}
//Return decrypted string
public function stringDecrypt ($encodedText, $cryptKey = '7R7zX2Urc7qvjhkr') {
$c = base64_decode($encodedText);
$cipher = 'aes-128-cbc';
if (in_array($cipher, openssl_get_cipher_methods()))
{
$ivlen = openssl_cipher_iv_length($cipher);
$iv = substr($c, 0, $ivlen);
$hmac = substr($c, $ivlen, $sha2len=32);
$ivlenSha2len = $ivlen+$sha2len;
$ciphertext_raw = substr($c, $ivlen+$sha2len);
$plainText = openssl_decrypt(
$ciphertext_raw, $cipher, $cryptKey, $options=OPENSSL_RAW_DATA, $iv);
}
return $plainText;
}
Upvotes: 1
Reputation: 14752
Your first link is about the command-line tools, not the PHP functions. You'd have a hard time throwing binary data in a terminal, hence why the key there has to be hex-encoded.
In PHP however, openssl_encrypt()
and openssl_decrypt()
expect a raw binary string.
The documentation is also misleading in that it mentions a 'password' instead of 'key'. You've noticed that, but an encryption key is not something that you should just type in via your keyboard and md5()
-ing anything is also never the answer for an encryption key.
The key has to be randomly generated via openssl_random_pseudo_bytes()
(or at least that's the most convenient way for your case):
$key = openssl_random_pseudo_bytes(32);
(the same goes for IVs as well)
If you need to hex-encode the resulting $key
, just pass it to bin2hex()
, but the example that you gave is a bit broken ... you're doing double encryption. Encrypting the file contents via PHP is enough, you don't need to deal with the command line.
Please note that my answer is far from the whole story about doing encryption. You should also add authentication, proper padding, think carefully of how to manage & store your keys, etc.
If you want to learn about it, here's a fairly short, but still descriptive blog post that gives the right answers to key points that you should cover: http://timoh6.github.io/2014/06/16/PHP-data-encryption-cheatsheet.html
If what you need is to simply get the job done - use a popular encryption library, don't write your own.
Upvotes: 3