Decrypt AES-128 CBC - PHP - php

I have an encrypted message in AES-128 CBC in this format "f21fcc6677c9ba2335da551fa143cf08" and I'm trying to decrypt using a key in this format "cdff8db86efb418a8e492a29dba44869", I'm new to this and I can't seem to make it work, I tried this code with no success.
<?php
$simple_string = base64_decode('f21fcc6677c9ba2335da551fa143cf08');
echo $simple_string. "\n";
//echo $simple_string;
$ciphering = 'AES-128-CBC';
$iv_length = openssl_cipher_iv_length($ciphering);
$options = 0;
$encryption_key = 'cdff8db86efb418a8e492a29dba44869';
echo $encryption_key. "\n";
$decryption = openssl_decrypt($simple_string, $ciphering, $encryption_key, OPENSSL_RAW_DATA);
var_dump($decryption);
my output is
bool(false)
any ideas? I think I have to change the format of the encrypted message or the key, but don't find much in Google.

Related

Encrypting data in url

l have some data in json format e.g {"utm_source":"","utm_medium":"","utm_campaign":"","utm_term":"","utm_content":""} and l want to send them encrypted as uri to another domain (example.com/$encrypted_data) and then decrypt them. How can l do that (with PHP) so the encrypted string contains only those chars: [A-Z, a-z, 0-9, -, /] and decryption is possible using the specific key? I am using PHP 8.1
<?php
// Store a string into the variable which
// need to be Encrypted
$simple_string = "Welcome to GeeksforGeeks\n";
// Display the original string
echo "Original String: " . $simple_string;
// Store the cipher method
$ciphering = "AES-128-CTR";
// Use OpenSSl Encryption method
$iv_length = openssl_cipher_iv_length($ciphering);
$options = 0;
// Non-NULL Initialization Vector for encryption
$encryption_iv = '1234567891011121';
// Store the encryption key
$encryption_key = "GeeksforGeeks";
// Use openssl_encrypt() function to encrypt the data
$encryption = openssl_encrypt($simple_string, $ciphering,
$encryption_key, $options, $encryption_iv);
// Display the encrypted string
echo "Encrypted String: " . $encryption . "\n";
// Non-NULL Initialization Vector for decryption
$decryption_iv = '1234567891011121';
// Store the decryption key
$decryption_key = "GeeksforGeeks";
// Use openssl_decrypt() function to decrypt the data
$decryption=openssl_decrypt ($encryption, $ciphering,
$decryption_key, $options, $decryption_iv);
// Display the decrypted string
echo "Decrypted String: " . $decryption;
?>
output
Original String: Welcome to GeeksforGeeks
Encrypted String: hwB1K5NkfcIzkLTWQeQfHLNg5FlyX3PNUA==
Decrypted String: Welcome to GeeksforGeeks
You can use openssl_decrypt() for decrypting data in PHP. you can read more about openssl_decrypt(); to know more how handle decrypt and encrypt string

(ssg-wsg) How to do AES Encryption in SSG-WSG API with Initialization Vector in PHP

I am trying to encrypt the payload with the AES encryption like below for SSG-WSG API. But I keep getting
Failed to parse JSON request content
I think something is wrong with my way of encryption. I am doing this in PHP.
<pre>
$cipher = "aes-256-cbc";
$ekey = "encryption key provided to SSG"
//Generate a 256-bit encryption key
$encryption_key = $ekey;
// Generate an initialization vector
$iv_size = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($iv_size);
//Data to encrypt
$data = $f; // payload in f
$encrypted_data = openssl_encrypt($data, $cipher, $encryption_key, 0, $iv);
$x = base64_encode($encrypted_data);
</pre>
Where is the SSGAPIInitVector initialization vector to be used, and how?
Thanks
Based on the openssl_encrypt library documentation, the 5th paramenter $iv is for the initialisation vector value. So, I believe you have to replace what you are doing which randomly generates a random Initialisation Vector to the fixed value provided.

openssl_decrypt tag value

I'm using the openssl_encrypt / decrypt method in my website but i'm having some troubles with the $tag option
openssl_encrypt ( $data, $method, $key, $options, $iv, $tag )
openssl_decrypt ( $data, $method, $key, $options, $iv, $tag )
from http://php.net/manual/en/function.openssl-encrypt.php, the definition of tag is: The authentication tag passed by reference when using AEAD cipher mode (GCM or CCM). But i didn't understand it.
I tried it in my codes
$data = "text to be encrypted";
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
if (in_array($cipher, openssl_get_cipher_methods())){
$encryptedData = openssl_encrypt($data,$cipher,$key,$option,$iv,$tag);
echo $encryptedData;
$decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
echo $decryptedData;
}
i got this result:
encrypted text: Vlx/yKkPhg0DpD0YKvnFKRiCh/I=
decrypted text: text to be encrypted
which is correct. but if i directly decrypt the encrypted text this way:
$data = "text to be encrypted";
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$ivlen = openssl_cipher_iv_length($cipher);
$iv = openssl_random_pseudo_bytes($ivlen);
if (in_array($cipher, openssl_get_cipher_methods())){
$encryptedData = "Vlx/yKkPhg0DpD0YKvnFKRiCh/I=";
$decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
echo $decryptedData;
}
i'm getting:
Notice: Undefined variable: tag
if someone could explain to me why this is happening and what should be the value of $tags. thanks
The tag that PHP is complaining about is an essential aspect of AES when using GCM mode of operation. In this mode, not only does the AES block cipher get applied, but an authentication tag gets calculated as well. It is an array of bytes that represents a MAC (Message Authentication Code) that can be used to verify the integrity of the data and wen decrypting. That same tag needs to be provided to do that verification. See the Wikipedia page about Galois/Counter Mode for more details.
So in order to successfully decrypt that ciphertext, you need to capture the $tag variable resulting from the openssl_encrypt() invocation and feed it into the openssl_decrypt() invocation. You did not do that, hence the complaint about the missing tag. Note that the tag (typically) contains non-readable characters so it is more convenient to store it in a base64 encoded format.
In addition to the $tag variable, you should also provide the same value for the $iv variable to the openssl_decrypt() method as you used in the openssl_encrypt() invocation. Again, base64 encoding makes that easier.
A quick test below demonstrates all this, where I first modified your script to print more stuff and then used the provided script to decrypt:
$ php test1.php
iv base64-ed: vBKbi8c6vCyvWonV
plaintext: text to be encrypted
ciphertext base64-ed: z28spOd3UEDmj+3a8n/WK11ls7w=
GCM tag base64-ed: OIAggQCGUbPgmPN6lFjQ8g==
$ php test2.php
decrypted ciphertext: text to be encrypted
where the code for test2.php is the following:
$cipher = "aes-128-gcm";
$key = "0123456789abcdefghijklmnob123456";
$option = 0;
$iv = base64_decode("vBKbi8c6vCyvWonV");
if (in_array($cipher, openssl_get_cipher_methods())){
$encryptedData = "z28spOd3UEDmj+3a8n/WK11ls7w=";
$tag = base64_decode("OIAggQCGUbPgmPN6lFjQ8g==");
$decryptedData = openssl_decrypt($encryptedData,$cipher,$key,$option,$iv,$tag);
echo("decrypted ciphertext: ".$decryptedData."\n");
}

openssl_decrypt () function not working, returning null

i used openssl_encrypt and openssl_decrypt function but the decrypt part is not returning any value, whereas using the same key Encrypt is working fine.
here is the function which i used. the variable $decrypted always return a null .
every small help will be appreciated
function deCryption($value)
{
$methods = openssl_get_cipher_methods();
$clefSecrete = "flight";
echo '<pre>';
foreach ($methods as $method) {
//$encrypted = openssl_encrypt($texteACrypter, $method, $clefSecrete); ----this was used for encryption
$decrypted = openssl_decrypt($value, $method, $clefSecrete);
echo "value=".$decrypted;
echo $method . ' : '. $decrypted . "\n";
break;
}
echo '</pre>';
return $decrypted;
}
I had exactly the same problem, I then googled my question and ended up here, on the same question that I had asked. So I had to search elsewhere.
I found this article useful in explaining the shortcoming of the official php documentation. Another article with similar content is here.
In the end it boils down to the key/password. What the openssl_encrypt library expects is a key NOT A PASSWORD. And the size of key must be the size of cipher’s intrinsic key size. The first article says if you provide a longer key, the excess is discarded and a key shorter than expected is padded with zero, i.e. \x00 bytes. I have not tested this fact.
I have edited your code to read as below.
The idea I have used is that the size of the initial vector that a cipher expects is also the size of the key it expects. So here, I am passing a key not a password as you were doing. Simply find a way turning your password into a key.
In your code, you did not pass options and the iv (initialization vector).
The iv is a string the cipher 'mixes' with the plaintext before encryption. So what the cipher encrypts is this 'mixture'. Is this important? Yes! Without this 'mixing', a pair of identical plaintexts would result into a pair of identical ciphertexts, which can lead to an attack; if two identical plaintext-ciphertext pairs are not from the same user, these two users are using the same key! A unique iv for each plaintext therefore ensures that no two plaintexts result into identical ciphertexts. In other words, the iv is a salt.
$plaintext = 'Testing OpenSSL Functions';
$methods = openssl_get_cipher_methods();
//$clefSecrete = 'flight';
echo '<pre>';
foreach ($methods as $method) {
$ivlen = openssl_cipher_iv_length($method);
$clefSecrete = openssl_random_pseudo_bytes($ivlen);
$iv = openssl_random_pseudo_bytes($ivlen);
$encrypted = openssl_encrypt($plaintext, $method, $clefSecrete, OPENSSL_RAW_DATA, $iv);
$decrypted = openssl_decrypt($encrypted, $method, $clefSecrete, OPENSSL_RAW_DATA, $iv);
echo 'plaintext='.$plaintext. "\n";
echo 'cipher='.$method. "\n";
echo 'encrypted to: '.$encrypted. "\n";
echo 'decrypted to: '.$decrypted. "\n\n";
}
echo '</pre>';

Encrypt file with PHP OpenSSL

Usually, I use openssl_encrypt to encrypt simple string with AES in PHP, and it works pretty well.
Now I need to encrypt files with AES-256-CTR mode, but the only way to do this is to file_get_contents the entire content of the file and then send it to the openssl_encrypt function to encrypt the actual file data. The problem is this method is very "poor" because of the critical waste of memory.
1) Is there a way to work with chunked data with PHP OpenSSL ?
For example:
<?php
// ...
$f = fopen('large.iso','r');
while(feof($f)){
$chunk = fread($f,16);
$cipher = openssl_encrypt(...$chunk...);
// ... code ...
}
// ... more code ...
?>
2) openssl_encrypt official documentation is not published yet. Does someone could clarify the meaning of the parameters of the function for use with AES-CTR mode? Does the counter is handled automatically? Is it necessary to apply a manual XOR the data returned by the function?
Note: It is a professional project so I don't want to use phpseclib or others' "anonymous" libraries, nor do I don't want to use the command line as well.
Looks like for php it's not possible to use aes-256-ctr without temporary file.
But for next chiper types:
OPENSSL_CIPHER_RC2_40
OPENSSL_CIPHER_RC2_128
OPENSSL_CIPHER_RC2_64
OPENSSL_CIPHER_DES
OPENSSL_CIPHER_3DES
OPENSSL_CIPHER_AES_128_CBC
OPENSSL_CIPHER_AES_192_CBC
OPENSSL_CIPHER_AES_256_CBC
you can use generating key on the fly:
$res = openssl_pkey_new('chiper args here');
openssl_pkey_export($res, $private_key);
$public_key = openssl_pkey_get_details($res);
$public_key = $public_key["key"];
Then encrypt:
$crypted_text = openssl_get_privatekey($private_key,'your data');
And decrypt:
openssl_public_decrypt($crypted_text,$decrypted_text,$public_key);
So if you don't want to use files, may be switching to OPENSSL_CIPHER_AES_256_CBC will help you?
1) It should be something like this:
function strtohex($x) {
$s = '';
foreach (str_split($x) as $c){
$s.=sprintf("%02X", ord($c));
}
return($s);
}
$method = "aes-256-ctr"; //aes-256-cbc
echo "Selected method: ".$method."<br /><br />";
$textToEncrypt = "My chunk of data";
$iv = "1234567890123456";
$pass = 'some_pass';
$dec_iv = strtohex($iv);
$key = strtohex($pass);
$enc_data = openssl_encrypt($textToEncrypt, $method, $pass, true, $iv);
echo "Encrypted message (openssl): ".$enc_data."<br />";
$dec_data = openssl_decrypt($enc_data, $method, $pass, OPENSSL_RAW_DATA, $iv);
echo "Decrypted message (openssl): ".$dec_data."<br />";
For CTR $iv should be unique for each chunk or your data can be broken.
2) I know only abot difference betwen CBC and CTR:
For CBC, the IV must be random, but not unique. It also must not be known.
For CTR, the IV must be unique and not known, but does not need to be random.

Categories