(PHP 5 >= 5.3.0)
openssl_encrypt — Encrypts data
$data
, string $method
, string $password
[, int $options
= 0
[, string $iv
= ""
]] )Encrypts given data with given method and key, returns a raw or base64 encoded string
本函数还未编写文档,仅有参数列表。
data
The data.
method
The cipher method.
password
The password.
options
options
can be one of
OPENSSL_RAW_DATA
,
OPENSSL_ZERO_PADDING
.
iv
A non-NULL Initialization Vector.
Returns the encrypted string on success 或者在失败时返回 FALSE
.
Emits an E_WARNING
level error if an unknown cipher
algorithm is passed in via the method
parameter.
Emits an E_WARNING
level error if an empty value is passed
in via the iv
parameter.
版本 | 说明 |
---|---|
5.3.3 |
The iv parameter was added.
|
5.4.0 |
The raw_output was changed to options .
|
kasper at webmasteren dot eu (2012-09-14 11:36:12)
For security reasons, if NOT encrypting using a (cryptographically) random IV, then the IV itself must be entryptet as well ( this is not handled behind the scene).
the reason is that it leads to predictable IV's, which then breaks semantic security. [this kind of attack can already be done on ssl/ TLS 1.1].
max (2012-08-01 02:35:54)
Might be useful to people trying to use 'aes-256-cbc' cipher (and probably other cbc ciphers) in collaboration with other implementations of AES (C libs for example) that the openssl extension has a strict implementation regarding padding bytes. I found the solution only by manually going through the openssl source.
In C, you would want to pad plaintexts the following way (assuming all mem allocations are proper):
nPadding = ( 16 - ( bufferSize % 16 ) ) ? ( 16 - ( bufferSize % 16 ) ) : 16;
for( index = bufferSize; index < bufferSize + nPadding; index++ )
{
plaintext[ index ] = (char)nPadding;
}
while decryptions are validated like:
isSuccess = TRUE;
for( index = bufferSize - 1; index > ( bufferSize - nPadding ); index-- )
{
if( plaintext[ index ] != nPadding )
{
isSuccess = FALSE;
break;
}
}
decryptedSize = bufferSize - nPadding;
In plain english, the buffer must be padded up to blockSize. If the buffer is already a multiple of blockSize, you add an entire new blockSize bytes as padding.
The value of the padding bytes MUST be the number of padding bytes as a byte...
So 5 bytes of padding will result in the following bytes added at the end of the ciphertext:
[ 0x05 ][ 0x05 ][ 0x05 ][ 0x05 ][ 0x05 ]
Hope this saves someone else a few hours of their life.
kazaaknet at yahoo dot com (2012-07-10 17:23:06)
Be advised there was a memory leak in this function: https://bugs.php.net/bug.php?id=54060. I believe this got fixed in 5.3.6, but on production webservers running 5.3.5 with modest traffic, this became a memory hemorrhage that brought my site down. Look at mcrypt_encrypt instead.
Kukulkan (2012-05-21 15:39:53)
PHP OpenSSL functions openssl_encrypt() and openssl_decrypt() seem to use PKCS5/7 style padding for all symmetric ciphers. Upon this, you can't use them to encrypt using null byte padding or to decrypt null byte padded data.
The developers of the wrapper forgot the padding scheme flags... :(
biohazard dot ge at gmail dot com (2011-06-15 06:48:56)
Many users give up with handilng problem when openssl command line tool cant decrypt php openssl encrypted file which is encrypted with openssl_encrypt function.
For example how beginner is encrypting data:
<?php
$string = 'It works ? Or not it works ?';
$pass = '1234';
$method = 'aes128';
file_put_contents ('./file.encrypted', openssl_encrypt ($string, $method, $pass));
?>
And then how beginner is trying to decrypt data from command line:
# openssl enc -aes-128-cbc -d -in file.encrypted -pass pass:123
Or even if he/she determinates that openssl_encrypt output was base64 and tries:
# openssl enc -aes-128-cbc -d -in file.encrypted -base64 -pass pass:123
Or even if he determinates that base64 encoded file is represented in one line and tries:
# openssl enc -aes-128-cbc -d -in file.encrypted -base64 -A -pass pass:123
Or even if he determinates that IV is needed and adds some string iv as encryption function`s fourth parameter and than adds hex representation of iv as parameter in openssl command line :
# openssl enc -aes-128-cbc -d -in file.encrypted -base64 -pass pass:123 -iv -iv 31323334353637383132333435363738
Or even if he determinates that aes-128 password must be 128 bits there fore 16 bytes and sets $pass = '1234567812345678' and tries:
# openssl enc -aes-128-cbc -d -in file.encrypted -base64 -pass pass:1234567812345678 -iv -iv 31323334353637383132333435363738
All these troubles will have no result in any case.
BECAUSE THE PASSWORD PARAMETER DOCUMENTED HERE IS NOT THE PASSWORD.
It means that the password parameter of the function is not the same string used as [-pass pass:] parameter with openssl cmd tool for file encryption decryption.
IT IS THE KEY !
And now how to correctly encrypt data with php openssl_encrypt and how to correctly decrypt it from openssl command line tool.
<?php
function strtohex($x)
{
$s='';
foreach (str_split($x) as $c) $s.=sprintf("%02X",ord($c));
return($s);
}
$source = 'It works !';
$iv = "1234567812345678";
$pass = '1234567812345678';
$method = 'aes-128-cbc';
echo "\niv in hex to use: ".strtohex ($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 ".strtohex($iv);
echo 'executing: '.$exec."\n\n";
echo exec ($exec);
echo "\n";
?>
IV and Key parameteres passed to openssl command line must be in hex representation of string.
The correct command for decrypting is:
# openssl enc -aes-128-cbc -d -in file.encrypted -nosalt -nopad -K 31323334353637383132333435363738 -iv 31323334353637383132333435363738
As it has no salt has no padding and by setting functions third parameter we have no more base64 encoded file to decode. The command will echo that it works...
: /
public at grik dot net (2010-08-01 17:25:09)
In 5.3.3 they added a new parameter, string $iv (initialization vector)
Real parameters are:
string openssl_encrypt ( string $data , string $method , string $password, bool $raw_output = false, string $iv )
If $iv is missing, a warning is issued: "Using an empty Initialization Vector (iv) is potentially insecure and not recommended".
If $iv is too short, another warning:
"IV passed is only 3 bytes long, cipher expects an IV of precisely 8 bytes, padding with \0"
same IV should be used in openssl_decrypt()
public at grik dot net (2009-12-25 09:54:02)
The list of methods for this function can be obtained with openssl_get_cipher_methods();
The password can be encrypted with the openssl_private/public_encrypt()