I am trying to encrypt a string in php using AES-128 and CBC, but when I call mcrypt_generic_init() it returns false.
$cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '',MCRYPT_MODE_CBC, '');
$iv_size = mcrypt_enc_get_iv_size($cipher);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$res = mcrypt_generic_init($cipher, 'aaaa', $iv); //'aaaa' is a test key
Can someone tell me why is returning 0/false? I read the php documentation and seems correct
(http://us.php.net/manual/en/mcrypt.examples.php)
I am trying to encrypt a string in php using AES-128 and CBC,
Are you sure about that? AES-CBC doesn't offer message integrity. This makes your application vulnerable to a padding oracle attack.
Also, mcrypt is a bad library.
Related
I am working on a project that requires the AES encryption of a soap envelope using the requirements below.
Encryption key: myKey-1234567abcdef
AES-256 encryption
128 block size
PKCS7 padding
16 bit vector (vector is attached before encrypted message)
Cipher Block Chaining (CBC)
This is what I tried:
$key = 'myKey-1234567abcdef';
$encryptionMethod = "AES-256-CBC";
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$iv = substr(mcrypt_create_iv($iv_size, MCRYPT_RAND), 0, 16);
$xml = openssl_encrypt($xml,$encryptionMethod, $key, 0, $iv);
I am currently getting a 400 bad request error and there seems to be lots of options for argument constants mcrypt functions, was wondering if my implementation satisfies the needs for padding, block size and vector?
I appreciate any suggestions, thanks in advance!
First: Your key isn't an appropriate length for AES-256. I realize the key you're using here is an example, but make sure that the one you've been provided is 32 characters (256 bits) long. If it isn't, ask the recipient for clarification.
Second: You're mixing the mcrypt and openssl extensions inappropriately here. You shouldn't be using mcrypt anyway, as it's unmaintained, sometimes broken, and will be removed entirely in PHP 7.2. Instead, hard-code the IV size as 16 and use openssl_random_pseudo_bytes to generate it:
$iv = openssl_random_pseudo_bytes(16);
$xml = openssl_encrypt($xml, $encryptionMethod, $key, 0, $iv);
Third: By default, openssl_encrypt() encodes its output as Base64. The recipient may not be expecting this. Pass OPENSSL_RAW_DATA as the fourth argument to openssl_encrypt() (replacing 0) to get unencoded output.
I got the following requirements for the encryption for the API i am currently trying to access:
PKCS7 padding method
CBC encryption mode
AES key size 256, block size 128
Everytime i submit to the API with the encryption, there seems to be something wrong with the API (unfortunately no error is produced).
$Data = "GOOD!";
$aesKey = "1234567812345678";
$EncryptedData = encrypt($aesKey,$Data);
$DecryptedData = decrypt($aesKey,$EncryptedData);
echo "Orignal Data : ". $Data;
echo "<br/>";
echo "After encryption = ". $EncryptedData;
echo "<br/>";
echo "After decryption = " .$DecryptedData;
function encrypt($aesKey, $dataToEncrypt) {
$output = false;
$iv = '{{{{{{{{{{{{{{{{';
$output = openssl_encrypt($dataToEncrypt, 'AES-128-CBC', $aesKey,
OPENSSL_RAW_DATA, $iv);
$output = base64_encode($output);
return $output;
}
function decrypt($aesKey, $dataTodecrypt) {
$output = false;
$iv = '{{{{{{{{{{{{{{{{';
$dataTodecrypt = base64_decode ($dataTodecrypt);
$dataTodecrypt = $output = openssl_decrypt($dataTodecrypt, 'AES-128-CBC',
$aesKey, OPENSSL_RAW_DATA, $iv);
return $output;
}
Questions:
What exactly is PKCS7 padding method and can be implemented with php?
AES 256 is fine but what exactly does block size mean?
What exactly does IV do?
AES 256 is fine but what exactly does block size mean?
AES has a fixed block size of 128 bit. A block cipher only works on one block of a specific size. A mode operation extends a block cipher with the ability to work on multiple blocks and a padding enables it to work on plaintexts that are not a multiple of the block size.
AES-128-CBC means AES with key size of 128 bit and the CBC mode of operation. If you want to use AES-256, then you need to tell OpenSSL that: AES-256-CBC. Additionally, you need to use a key that is actually 256 bit long. Your current key is only 128 bit long.
What exactly is PKCS7 padding method and can be implemented with php?
openssl_encrypt() already does PKCS#7 padding for you and openssl_decrypt() removes it for you.
What exactly does IV do?
A random IV randomizes the ciphertext which means that encrypting the same plaintext with the same key, but a different IV produces a different ciphertext which is indistinguishable from random noise or other the same encryption with a different IV. Wikipedia has a good description what this actually does.
Keep in mind that an IV must be randomly generated for each iteration. Otherwise, an attacker who observes only the ciphertext may discover that you encrypted the same plaintext multiple times.
Keep in mind that an AES key is supposed to be quite noisy with high entropy. "12345..." looks more like a password. If you want to use passwords, then you need to derive a key from that password. PBKDF2 is a good idea with a random salt and a lot of iterations.
What exactly is PKCS7 padding method and can be implemented with php?
I am not really certain 'padding' is the phrase you mean here. While the PKCS#7 format does rely on padding, the example you provide has absolutely nothing to do with asymmetric encryption and the ASN.1 format for the PKCS#7 messaging syntax mentioned.
AES 256 is fine but what exactly does block size mean?
Block size is the bit size an encryption cipher, like AES-256, operates on per permutation.
What exactly does IV do?
An IV is short for initialization vector or for some symmetric encryption cipher implementations it can also be referred to as an nonce.
Both are used to help strengthen the resulting cipher text. You can think of them as being similar to a salt for a non-reversible hashing algorithm.
You should avoid re-using the same IV.
In regards to your example; the documentation for openssl_encrypt() states the following function usage:
string openssl_encrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )
Your encryption of the plain text looks accurate (while I would choose AES-256-GCM vs. AES-128-CBC as the algorithm, blocksize & mode):
$output = openssl_encrypt($dataToEncrypt, 'AES-128-CBC', $aesKey,
OPENSSL_RAW_DATA, $iv);
Without testing I am assuming you are getting a valid base64 encoded value.
The manual for the openssl_decrypt() method states the following usage:
string openssl_decrypt ( string $data , string $method , string $password [, int $options = 0 [, string $iv = "" ]] )
While technically your implementation is correct; I would suggest the following (note the double assignment to $dataTodecrypt = $output = openssl_decrypt()):
$output = openssl_decrypt(base64_decode($dataTodecrypt), 'AES-128-CBC', $aesKey, OPENSSL_RAW_DATA, $iv);
I use PHP 5.3.3 and is trying to do a blowfish encryption with these options:
The bytes of the encrypted data are hex-coded and left padded up to two characters with a zero. Blowfish ECB is used for encryption with a attached salt.
It's from an integration manual of EVO payments international (creditcard payments).
Can I use crypt()? (password_hash() is not available in 5.3)
If anyone is looking for an answer to this, here is my solution:
$cipher = mcrypt_module_open(MCRYPT_BLOWFISH, '', MCRYPT_MODE_ECB, '');
$iv = '12345678'; //this is ignored when using MCRYPT_MODE_ECB
mcrypt_generic_init($cipher, $blowfish_secret, $iv);
$data_blowfish = mcrypt_generic($cipher, $datastring_to_encrypt);
mcrypt_generic_deinit($cipher);
return bin2hex($data_blowfish);
It seems to work
I have a situation where I have to encrypt and decrypt SOAP xml in PHP. I am trying to encrypt the Envelope of a soap xml. Encryption is working, but decryption is not. For encryption and decryption I use the code specified in this article:
http://blog.djekldevelopments.co.uk/?p=334
If the input string contains any special characters(eg:'<>'), then decryption is not working. How can I solve this?
function decrypt($string = "")
{
$keyfile = "./AES.keyz";
$keyfile = file($keyfile);
$key = base64_decode($keyfile[0]);
$iv = base64_decode($keyfile[1]);
$string = base64_decode($string);
return strippadding(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $string,MCRYPT_MODE_CBC, $iv));
}
MCRYPT_RIJNDAEL_256 ia not AES with 256 bit key , its RIJNDAEL with a 256 bit block size.
To decrypt 256 bit AES , you need to use MCRYPT_RIJNDAEL_128 with a 256 bit key.
I am trying to pass some encrypted data to a flash , but I got stuck somewhere in the middle.
Im using RIJNDAEL algorithm to encode the data in PHP :
function encrypt($text){
$key = "53cded30ff7ba54d65b939fd594e3d63";
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); //get vector size on CBC mode
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND); //Creating the vector
$cryptedtext = mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv); //Encrypting using MCRYPT_RIJNDAEL_256 algorithm
return $cryptedtext;
}
And im using the AS3CRYPT library to decrypt the value in flash.
The problem is that if I try to decode the value in flash or even in the demo of AS3CRYPT, it doesnt work.
I also tried to return the data from PHP encoded with base64_encode but still not working.
The output from PHP is something like : flashvar=Á žJcV—µg)7¾1´‘5{Ò<¶Ù$þS„§”
Probably I did something wrong in the PHP ...
PHP doesn't add any padding, which is likely needed.
You'll have to pad it manually, take a look at this post on PHP.net which explains one method of achieving PKCS7 padding compatibility.
Beyond that, make sure you're setting the matching confidentiality mode (CBC) and cipher within "AS3CRYPTO".