Php openSLL Encryption - to prevent special characters - php

I want to create and encryption for get variabile passed in url and for asynchronous call
for example:
$textToEncrypt = "Hello World";
$encryptionMethod = "AES-256-CBC";
$secretHash = "cVb67YtfAz328oOikl96vBn";
$iv = "adfrf54dmnlo09ax";
$encryptedText = openssl_encrypt($textToEncrypt,$encryptionMethod,$secretHash, 0, $iv);
result is: W2p0S2qlSierJnIcA/AM3g==
there are some special characters, == always at the end. I want to prevent this! How can I output only 0-9 and A-Z and a-z characters?
thanks

I had the same issue. I wanted to remove the special characters. So, this is what I did. Convert the encrypted text into hex value using base64_encode($encryptedText). So, there will be no special characters. Then for the revert, use base64_decode before passing to openssl_decrypt.

$ciphering = "AES-128-CTR";
use this as your cipher string, it'll remove any type of == from the end

I notice I had exactly 2 equal signs at the end of my encrypted string too. It seems theres always 2 equal signs at the end. Here's my solution
function encryptString($string, $action, $baseIP = 'false', $extraKey = ''){
global $flag;
$encryptedIP = '';
if($baseIP){
$encryptedIP = encryptString($_SERVER['REMOTE_ADDR'], 'encrypt', false);
}
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = $flag['2nd-encrypt-key'].$encryptedIP.'-'.$extraKey;
$secret_iv = $flag['2nd-encrypt-secret'].$encryptedIP.'-'.$extraKey;
$key = hash('sha256', $secret_key);
$iv = substr(hash('sha256', $secret_iv), 0, 16);
$output;
if($action == 'encrypt'){
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
//replace equal signs with char that hopefully won't show up
$output = str_replace('=', '[equal]', $output);
}else if($action == 'decrypt'){
//put back equal signs where your custom var is
$setString = str_replace('[equal]', '=', $string);
$output = openssl_decrypt(base64_decode($setString), $encrypt_method, $key, 0, $iv);
}
return $output;
}

Related

Encryption function returns different Encrypted key?

I am using this function to encrypt a string :
function encrypt_decrypt($action, $string)
{
$output = false;
$encrypt_method = 'AES-256-ECB';
$secret_key = 'gT4ThOvcaFDccFFV21mg5hPzglZsY73T';
$key = hash('sha256', $secret_key);
if ( $action == 'encrypt' )
{
$output = openssl_encrypt($string, $encrypt_method, $key, 0);
$output = base64_encode($output);
}
else if( $action == 'decrypt' )
{
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0);
}
return $output;
}
I am using this function in 2 php files (same function no changes at all )
the only difference between the 2 files is :
File1.php is getting the string in HTTP GET request:
$Email = htmlspecialchars($_GET["Email"]);
$ENC_Email = encrypt_decrypt("encrypt",$Email);
echo($ENC_Email);
and File2.php is getting the very same string from cookies:
$Email = $_COOKIE['Email'];
$enc = encrypt_decrypt("encrypt",$Email);
echo($enc);
echo of the variable $Email is same in both cases , but the resulting encrypted string is different.
What am I missing here ?
It's normal. You encrypt a string, it's not the samething as hashing a string. A hash will give you always the same result. But encryption use random salt, randomIV and differents other random parameters. Then the result is always different.
But, when you decrypt, you must get the string you have encrypted before.

Converting PHP encrypt/decrypt to Node.js

I have been trying to find out how to make this:
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'HqFdkh2FX126fH1r';
$secret_iv = 'iS2dk82dXd26f61K';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if( $action == 'decrypt' ) {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
In Node.js
The reason is that the encryption will be handled by PHP and the decryption by Node.
EDIT:
I managed to get this far:
var crypto = require('crypto')
, key = 'cI8Jd96NDoasd09jcI8Jd96NDoasd09j'
, iv = 'cI8Jd96NDoasd09j'
, plaintext = '2';
hashedKey = crypto.createHash('sha256').update(key, 'utf-8').digest('hex');
console.log('hashed key=', hashedKey);
// corresponds to the hashed key in PHP
hashedIv = crypto.createHash('sha256').update(iv, 'utf-8').digest('hex').substring(0,16);
console.log('hashed iv=', hashedIv);
// corresponds to the hashed iv in PHP
var buf = Buffer.from(teamId, 'base64');
console.log("buffer: " + buf);
and the variable buf actually is the same as base64_decode($string in the PHP code.
However, when I do this:
var decipher = crypto.createDecipheriv("aes-256-cbc",key, iv);
var decrypted = decipher.update(buf, 'base64', 'utf8');
console.log("decrypted.toString(): " + decrypted.toString());
I'm getting Z���ߋd�M:�� in the console rather than the desired 2.
The main problem was an embarrasing one. We are mainly two devs on this project and I thought the php-file I was editing for the encryption and decryption was the only thing I had to care about.
It was later realized that the actual call for the encoding was made from another php-file. Thus, what I changed in the encoding in the file I was working on was all in vain.
The end result looks like this, for anyone who's interested:
function encrypt_decrypt($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = '32 byte key';
$secret_iv = '16 byte iv';
// hash
$key = substr(hash('sha256', $secret_key), 0, 32);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if ( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
//$output = base64_encode($output);
} else if( $action == 'decrypt' ) { // this below is now handled in Node
$output = openssl_decrypt($string, $encrypt_method, $key, 0, $iv);
//$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
And Node:
function getDecryptedTeamId(encryptedId) {
var hashedKey;
var hashedIv;
var crypto = require('crypto')
, key = 'same 32 byte key as above in php'
, iv = 'same 16 byte ivas above in php'
, plaintext = '2';
hashedKey = crypto.createHash('sha256').update(key, 'utf-8').digest('hex').substring(0,32);
key = hashedKey;
hashedIv = crypto.createHash('sha256').update(iv, 'utf-8').digest('hex').substring(0,16);
iv = hashedIv;
var buf = Buffer.from(encryptedId, 'base64');
var crypt = buf.toString('base64');
var decryptor = crypto.createDecipheriv("aes-256-cbc", hashedKey, hashedIv);
var teamIdDec = decryptor.update(buf);
teamIdDec += decryptor.final();
return teamIdDec;
}

Why does file encryption using mcrypt fail?

I have an issue using mcrypt to encrypt a file on filesystem to e.g. store it into Mysql database. I have reduced the issue to the following lines of code:
<?php
$key = vzc_generateKey();
$file_content = file_get_contents("test.pdf"); // Fails
$file_content = file_get_contents("test2.docx"); // Fails
//$file_content = "12323"; // Works great
$hash_start = md5($file_content);
$encrypt = vzc_encryptV3($file_content, $key);
$decrypt = vzc_decryptV3($encrypt, $key);
$hash_end = md5($decrypt);
echo ($hash_end == $hash_start)."##";
function vzc_generateKey()
{
$cstrong = false;
while ($cstrong == false)
{
$bytes = openssl_random_pseudo_bytes(16, $cstrong);
}
return bin2hex($bytes);
}
function vzc_decryptV3($crypt,$key) {
$content = base64_decode($crypt['crypt']);
$iv = $crypt['iv'];
$rijndael = 'rijndael-256';
$cp = mcrypt_module_open($rijndael, '', 'ofb', '');
$ks = mcrypt_enc_get_key_size($cp);
$key = substr(md5($key), 0, $ks);
mcrypt_generic_init($cp, $key, $iv);
$decrypted = mdecrypt_generic($cp, $content);
mcrypt_generic_deinit($cp);
mcrypt_module_close($cp);
return trim(base64_decode($decrypted));
}
function vzc_encryptV3($file_content,$key) {
$content = base64_encode($file_content);
$rijndael = 'rijndael-256';
$cp = mcrypt_module_open($rijndael, '', 'ofb', '');
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cp), MCRYPT_RAND);
else
$iv = mcrypt_create_iv(mcrypt_enc_get_iv_size($cp), MCRYPT_DEV_RANDOM);
$ks = mcrypt_enc_get_key_size($cp);
$key = substr(md5($key), 0, $ks);
mcrypt_generic_init($cp, $key, $iv);
$encrypted = mcrypt_generic($cp, $content);
$returnvalue = array("crypt"=>trim(base64_encode($encrypted)), "iv"=>$iv);
mcrypt_generic_deinit($cp);
mcrypt_module_close($cp);
return $returnvalue;
}
?>
Using the String "12323" everything works fine, both Hashes do equal. But those two test files (one pdf and one docx) fail. It seems that the decryption returns different values then the origin data.
What can I do to solve this issue?
Thank you very much in advance for any tip you can provide.
It is probably the fact that the files are not exactly n * blocksize long. This leads the algorithm to pad the end of the file with '\0' and this changes the content of the file when you do the md5 calculation.
One way around this is to strip the padding off of the last block, if you can reliably find the end of the file.

How to create two way encode/decode methods using use-specific key - PHP?

I need two functions/methods, one to encode, one to decode. This is not for storing passwords. Each user will have a specific key/salt to encode the data.
This is how I would like it to work:
function encode($str, $key) {
// something fancy
}
function decode($str, $key) {
// something fancy
}
$key = $logged_in_user->get_key();
$plain = 'abc abc 123 123';
$encoded_data = encode($plain, $key);
// some_fancy_encrypted_data_that_is_really_cooooool
$decoded_data = decode($encoded_data, $key);
// abc abc 123 123
Another thing is that every time I use this function it needs to return the same thing every time I use the encode function with the same user key.
How would I do this??
$myVarIWantToEncodeAndDecode
Define key (salt, broth etc..): $key = "#&$sdfdfs789fs7d";
To encode:
$encoded = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $myVarIWantToEncodeAndDecode, MCRYPT_MODE_CBC, md5(md5($key))));
To decode:
$decoded = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encoded), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
Note: mcrypt_decrypt has been DEPRECATED as of PHP 7.1.0. Relying on this function is highly discouraged.
Use openssl_encrypt instead of mcrypt_encrypt
mcrypt_encrypt DEPRECATED as of PHP 7.1.0 and REMOVED as of PHP 7.2.0.
So, Try this..
function encrypt_decrypt($string, $action = 'encrypt')
{
$encrypt_method = "AES-256-CBC";
$secret_key = 'AA74CDCC2BBRT935136HH7B63C27'; // user define private key
$secret_iv = '5fgf5HJ5g27'; // user define secret key
$key = hash('sha256', $secret_key);
$iv = substr(hash('sha256', $secret_iv), 0, 16); // sha256 is hash_hmac_algo
if ($action == 'encrypt') {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
} else if ($action == 'decrypt') {
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
echo "Your Encrypted password is = ". $pwd = encrypt_decrypt('spaceo', 'encrypt');
echo "Your Decrypted password is = ". encrypt_decrypt($pwd, 'decrypt');

PHP mycrypt problem, weird characters/warnings

I have no idea what I'm doing wrong. I just need to be able to encrypt and decrypt without getting weird characters or warnings. It says I'm supposed to be using an IV of length 16 and that I'm using a length of 9 but "0123456789abcdef" is 16 characters.
Warning: mcrypt_generic_init() [function.mcrypt-generic-init]: Iv size incorrect; supplied length: 9, needed: 16 in /home/mcondiff/public_html/projects/enc/enc.php on line 10
See http://www.teamconcept.org/projects/enc/enc.php
I'm lost, confused, a little lightheaded. Here do I go from here? I have to use this encryption and get it working for a project.
<?php
class enc
{
function encrypt($str, $key) {
$key = $this->hex2bin($key);
$td = mcrypt_module_open("rijndael-128", "", "cbc", "fedcba9876543210");
mcrypt_generic_init($td, $key, CIPHER_IV);
$encrypted = mcrypt_generic($td, $str);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return bin2hex($encrypted);
}
function decrypt($code, $key) {
$key = $this->hex2bin($key);
$code = $this->hex2bin($code);
$td = mcrypt_module_open("rijndael-128", "", "cbc", "fedcba9876543210");
mcrypt_generic_init($td, $key, CIPHER_IV);
$decrypted = mdecrypt_generic($td, $code);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
return utf8_encode(trim($decrypted));
}
function hex2bin($hexdata) {
$bindata = "";
for ($i = 0; $i < strlen($hexdata); $i += 2) {
$bindata .= chr(hexdec(substr($hexdata, $i, 2)));
}
return $bindata;
}
}
$theEncryption = new enc();
$user = "John Doe";
$email = "john#example.com";
$user = $theEncryption->encrypt($user, "0123456789abcdef");
$email = $theEncryption->encrypt($email, "0123456789abcdef");
echo 'User: '.$user;
echo 'Email: '.$email;
?>
Can somone point me in the right direction or point out what i'm doing wrong?
Thanks
Mike
CIPHER_IV is probably an undefined constant. PHP raises a "Use of undefined constant" notice and then uses the "constant" as string. The string "CIPHER_IV" is 9 characters long.
In your php file, do a print of CIPHER_IV and see what it contains.
See http://us2.php.net/mcrypt_generic_init for the specifics
You've probably copy-pasted the code from a blog: googling mcrypt_generic_init CIPHER_IV only gives this post and a blog ;)
The IV is a parameter that you need to specify to the function, not a constant that the first blogger put in misinterpreting the second blogger's article.
At http://propaso.com/blog/?cat=6, they declare these:
$secret_key = "01234567890abcde";
$iv = "fedcba9876543210";
and then do:
mcrypt_generic_init($td, $secret_key, $iv);
Simply declare your IV to be something, then use it.

Categories