php decryption failing from URL - php

I am using php decrypion to check that: an email address replying to a request is the same email address which was sent the request.
This is the code but at the bottom it simpy fails.
The url is simply:
blah.com/page?keyemail=fSHEk8KC17siklGHsj0HJA==
The code below also shows some tests i did to make sure the encrypt/decrypt were working ok... I echo'd down the code to see what was going on
$key="XiTo74UI09wwe4YeUmuvbL0E";
$iv = mcrypt_create_iv (mcrypt_get_block_size (MCRYPT_TripleDES, MCRYPT_MODE_CBC), MCRYPT_DEV_RANDOM);
// Encrypting
function encrypt($string, $key) {
$enc = "";
global $iv;
$enc=mcrypt_cbc (MCRYPT_TripleDES, $key, $string, MCRYPT_ENCRYPT, $iv);
return base64_encode($enc);
}
// Decrypting
function decrypt($string, $key) {
$dec = "";
$string = trim(base64_decode($string));
global $iv;
$dec = mcrypt_cbc (MCRYPT_TripleDES, $key, $string, MCRYPT_DECRYPT, $iv);
return $dec;
}
// test example
$email = 'me#me.com';
echo "email is $email<br /><br />";
$email_key = encrypt($email, $key);
echo "key is $email_key<br /><br />";
$email_key2 = decrypt($email_key, $key);
echo "decrypted is $email_key2<br /><br />";
// END test example, all is ok
// this is the code that fails
$to_de = $_GET[keyemail];
echo "keyemail again is $to_de<br /><br />";
$email_key3 = decrypt($to_de, $key);
echo $email_key3;
What is being returned when I echo $email_key3 is encoded somehow - it should be me#me.com
I'm probably missing something obvious but it's lost me!

You can't generate a new IV on each page - you must either store the IV from the encryption step in a file or database - or append it to the encrypted string. Generating a new IV on the next page will not allow you to decrypt the string.
Also, if possible I would pass a hash of an the email (plus a salt) - not an encrypted form.

I've noticed that the encryption method you're using is adding a random salt. That means that encrypting the same string with the same key does not result in the same output.
Try using a non randomized KDF.
Try the answer of this topic: https://stackoverflow.com/a/1289114/1745542

Related

Mcrypt not decrypting

I'm working on a small program that has to encrypt a basic sentence and echo the result. Then I want to be able to copy paste the result and be able to decode the text in the same way I encoded it. It doesn't need to be too safe, so therefore I opted to use Mcrypt.
When I try to decrypt, it gives weird (ASCII?) letters and I don't understand where they come from. Tried to solve it with a base64 encode/decode, but that didn't help either. What do I need to change to get it to work properly?
<?php
// Define Mcrypt variables
$enc = MCRYPT_RIJNDAEL_128;
$mode = MCRYPT_MODE_CBC;
$key = 'SanderDitIsNodigVoor16bi';
$iv = mcrypt_create_iv(mcrypt_get_iv_size($enc, $mode), MCRYPT_DEV_URANDOM);
// Check if 'submit' is set
if (isset($_POST['submit'])) {
// Check if 'text' is set
if (!empty($_POST['text'])) {
// Check if 'crypt' is set
if (isset($_POST['crypt'])) {
// Retrieve 'text'
$input = $_POST['text'];
// Check for encrypt/decrypt
switch ($_POST['crypt']) {
case 'encrypt':
$result = encrypt();
break;
case 'decrypt':
$result = decrypt();
break;
}
echo $result;
}
// If 'crypt' is not set
else {
echo 'Please select encrypt or decrypt.';
}
}
// If 'text' is not set
else {
echo 'Please fill in some text.';
}
}
function encrypt() {
global $enc, $key, $input, $mode, $iv;
$encrypted = mcrypt_encrypt($enc, $key, $input, $mode, $iv);
$output = base64_encode($encrypted);
return $output;
}
function decrypt() {
global $enc, $key, $input, $mode, $iv;
$decrypted = base64_decode($input);
$output = mcrypt_decrypt($enc, $key, $decrypted, $mode, $iv);
return $output;
}
?>
To be clear, if I include the mcrypt_decrypt in the encryption to make sure it's not something I messed up in the function itself, it does decrypt it properly. But when I try to separate the two, it doesn't. I'm stumped.
you are sending to both encrypt and decrypt the same input , which is :
$input = $_POST['text'];
encrypt will encrypt successfully , but you are always trying to decrypt 'decrypted' phrase !
you must pass the encrypted phrase to decrypt function
and don't forget about the important note that mcrypt_* extension has been deprecated :
This extension rely in libmcrypt which is dead, unmaintained since
2007.
Please don't rely on it, consider switching to well maintained
alternatives (openssl, crypt, password hashing functions, phpseclib,
password_compat...)
and , try to stop using global variables , it isn't recommended .

encrypt and decrypt with diacrits

I have these code for encrypt and decrypt.
It works good for text (for example: "This is a text"), which is withnout diacritics (that means without : ěščřžýáíéúů).
But I need encrypt and decrypt text with this special letters (with : ěščřžýáíéúů).
Can somebody help me, please?
Thank so much for every answer and help.
Have a nice day. M.
define ("ENCRYPTION_KEY", "QaY7e4d1c");
$string= "This is a text"; // -> this work alright
//$string= "áýžřčšě"; I NEED THIS TEXT ENCRYPT AND DECRTYPT
echo $encrypted = encrypt($string, ENCRYPTION_KEY);
echo "<br />";
echo $decrypted = decrypt($encrypted, ENCRYPTION_KEY);
function encrypt ($pure_string,$encryption_key)
{
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH,$encryption_key,utf8_encode($pure_string),MCRYPT_MODE_ECB,$iv);
return $encrypted_string;
}
function decrypt ($encrypted_string,$encryption_key)
{
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH,MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);
$decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH,$encryption_key,$encrypted_string,MCRYPT_MODE_ECB ,$iv);
return $decrypted_string;
}
You're calling utf8_encode in your encryption function, but not calling utf8_decode when you decrypt, so your functions as they stand don't complement each other.
I'd recommend removing the call to utf8_encode entirely. mcrypt_encrypt doesn't care what encoding your string uses, so whatever you pass in will be what you get back out. Your script works fine for me if I remove it:
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $encryption_key, $pure_string, MCRYPT_MODE_ECB, $iv);
I'd also suggest reading this: https://paragonie.com/blog/2015/05/if-you-re-typing-word-mcrypt-into-your-code-you-re-doing-it-wrong

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.

mcrypt_decrypt wrong output after using encrypted data php

I have a small problem with php mcrypt_decrypt function. Firstly, I use a 16-byte string, and encrypt it using mcrypt_encrypt; then, I use base64_encode, and put the output to mcrypt_decrypt, in order to get the initial string.
But the output is not what's expected. I checked that my base64 decoded string input for decoding is the exact output produced by mcrypt_decrypt. Here is my code:
//encrypt
$str="KKQT9W4st7vmdkps";
$key="43625A8C1E4330BDF84DDEE3DD105037";
$block = mcrypt_get_block_size('rijndael_128', 'ecb');
$passcrypt=mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB);
echo $passcrypt;
That outputs PTfZ6Ephh8LTxXL4In33Og==. The decryption script is the following:
//decrypt
$str='PTfZ6Ephh8LTxXL4In33Og==';
$key='43625A8C1E4330BDF84DDEE3DD105037';
$str = base64_decode($str);
$str = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key,
$str, MCRYPT_MODE_ECB,''),"\0");
$block = mcrypt_get_block_size('rijndael_128', 'ecb');
echo $str;
And the output is not KKQT9W4st7vmdkps, but -nγ kk7Ζn’T instead. Any ideas? I'm using XAMPP and Apache server.
Thx guys for the feedback it was a silly mistake that i made...actually 'PTfZ6Ephh8LTxXL4In33Og==' was wrong in the decrypt function cause "I" was "l" in the end...so the decryption was not correct...but it was not my fault either since I was getting this string from a QR CODE scanner and both "I" and "l" are displayed the same...
For encryption, you need to:
1) Create an encryption resource
$str = "KKQT9W4st7vmdkps";
$key = "43625A8C1E4330BDF84DDEE3DD105037";
$r = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '',MCRYPT_MODE_ECB, '');
2) Randomly create encryption vector based on the size of $r
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($r),MCRYPT_RAND);
3) Initiliazing module using the resource,key and string vector
mcrypt_generic_init($r,$key,$iv);
4) Encrypt data/string using resource $r
$encrypted = mcrypt_generic($r,$str);
5) Encode it using base64_encode
$encoded = base64_encode($encrypted);
if(!mcrypt_generic_deinit($r) || !mcrypt_module_close($r))
$encoded = false;
6) Echoing it
echo 'Encrypted: '.$encoded;
For decryption, it's like a reverse process of encrypt
//Using the same enrypted string
$decoded = (string) base64_decode(trim($encoded));
$td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '',MCRYPT_MODE_ECB, '');
$ivs = mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
mcrypt_generic_init($td,$key, $ivs);
$decoded = (string) trim(mdecrypt_generic($td, $decoded));
if(!mcrypt_generic_deinit($td) || !mcrypt_module_close($td))
$decoded = false;
Echoing it
echo 'Decrypted: '. $decoded;
Hope this helps. More info here.

Categories