php mcrypt and different servers - php

i'v got such code
function EnDeCrypt($text, $key, $s = 1){
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
switch ($s) {
case '0':
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_ECB, $iv));
break;
case '1':
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_ECB, $iv));
break;
default:
return FALSE;
break;
}
}
if i call EnDeCrypt in one script, all works, if i try to pass encrypted data to different server in get param-i can't decrypt(get such string ŸTe³qëêyÀÝ)
key equals, result put throw urlencode\urldecode-don't decrypt
try to pass vector mcrypt_create_iv -nothing

To decypher, you need to have the same initialization vector ($iv) that was used to cypher.
Pass it as a parameter to your function and all should be fine.

Related

Using mcrypt for password encryption in php

I want to know that can I use this encrypt-decrypt script for password encryption and put it into database?
And what will be the sql table password column structure(currently it is password varchar(32) NOT NULL).
Please note that this script is using a 32-byte hexadecimal key as encryption key.
<?php
define('ENCRYPTION_KEY', '32-byte hexadecimal encryption key');
function mc_encrypt($encrypt, $key)
{
$encrypt = serialize($encrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC), MCRYPT_DEV_URANDOM);
$key = pack('H*', $key);
$mac = hash_hmac('sha256', $encrypt, substr(bin2hex($key), -32));
$passcrypt = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $encrypt.$mac, MCRYPT_MODE_CBC, $iv);
$encoded = base64_encode($passcrypt).'|'.base64_encode($iv);
return $encoded;
}
function mc_decrypt($decrypt, $key)
{
$decrypt = explode('|', $decrypt);
$decoded = base64_decode($decrypt[0]);
$iv = base64_decode($decrypt[1]);
if(strlen($iv)!==mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC)){ return false; }
$key = pack('H*', $key);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $decoded, MCRYPT_MODE_CBC, $iv));
$mac = substr($decrypted, -64);
$decrypted = substr($decrypted, 0, -64);
$calcmac = hash_hmac('sha256', $decrypted, substr(bin2hex($key), -32));
if($calcmac!==$mac){ return false; }
$decrypted = unserialize($decrypted);
return $decrypted;
}
?>
You should not store passwords - with or without encryption - unless strictly required (i.e. dealing with older protocols). Instead use a password hash function based on a PBKDF such as PBKDF2, bcrypt or scrypt.
Note that the encryption does not use AES but Rijndael with a block size of 256 bits. Also note that the key handling is suboptimal, it's easy to make mistakes with regards to the key parameter. Otherwise the code looks OK at first glance.

PHP sending encrypted data via the URL

I'm trying to send encrypted data over the url to another site (using file_get_contents("anotherUrl.php?hash=$encryptedString"). The problem is, sometimes, the encryption contains some special characters, like +, and this causes the decryption to fail.
Here are my encryption / decryption methods:
public function encrypt($string, $key)
{
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key))));
}
public function decrypt($encrypted, $key)
{
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($encrypted), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
}
Here's an example encrypted string which contains a +, and I'm guessing that this causes the decryption to fail.
oWCrVPaS+5GbxcQFc0fulUk/zRAkDD60av4zlPiWskE=
Any ideas how I should solve this? I've tried to do urlencode() and urldecode() on the hash, however that also seems to cause the encryption to break. Is there a way to change the encryption algorithm to get it to only return url safe characters?
Take a look at this thread:
Passing base64 encoded strings in URL
Essentially you DO want to urlencode() before sending the string, however you do NOT want to urldecode() at the other end.
In order to solve this problem I now use the following (after 3 hours of pain), and it works great.
Feel free to copy and paste
function encrypt($pure_string) {
$dirty = array("+", "/", "=");
$clean = array("_PLUS_", "_SLASH_", "_EQUALS_");
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_ECB);
$_SESSION['iv'] = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $_SESSION['encryption-key'], utf8_encode($pure_string), MCRYPT_MODE_ECB, $_SESSION['iv']);
$encrypted_string = base64_encode($encrypted_string);
return str_replace($dirty, $clean, $encrypted_string);
}
function decrypt($encrypted_string) {
$dirty = array("+", "/", "=");
$clean = array("_PLUS_", "_SLASH_", "_EQUALS_");
$string = base64_decode(str_replace($clean, $dirty, $encrypted_string));
$decrypted_string = mcrypt_decrypt(MCRYPT_BLOWFISH, $_SESSION['encryption-key'],$string, MCRYPT_MODE_ECB, $_SESSION['iv']);
return $decrypted_string;
}
Instead of using Base64 for encoding your data you can also use Base32 (RFC 4648) which is URL-safe because it only uses letters A–Z (case-insensitive) and the digits 2–7. There is already a PHP library for encoding/decoding. Note that Base32 takes ~20% more space than Base64.
You can also use URLcrypt which is a handy library helping you with encryption and Base32 encoding.
class Encryption {
var $skey = "SuPerEncKey2010"; // you can change it
public function safe_b64encode($string) {
$data = base64_encode($string);
$data = str_replace(array('+','/','='),array('-','_',''),$data);
return $data;
}
public function safe_b64decode($string) {
$data = str_replace(array('-','_'),array('+','/'),$string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
}
public function encode($value){
if(!$value){return false;}
$text = $value;
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->skey, $text, MCRYPT_MODE_ECB, $iv);
return trim($this->safe_b64encode($crypttext));
}
public function decode($value){
if(!$value){return false;}
$crypttext = $this->safe_b64decode($value);
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
$decrypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->skey, $crypttext, MCRYPT_MODE_ECB, $iv);
return trim($decrypttext);
}
}

Figure out mcrypt key when knowing hash and plain

i have 2 functions:
function Encrypt($sValue, $sSecretKey = "") {
if (!$sSecretKey) {
$sSecretKey = $GLOBALS['key'];
}
return trim(base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, $sValue, MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB),
MCRYPT_RAND))));
}
and
function Decrypt($sValue, $sSecretKey = "") {
if (!$sSecretKey) {
$sSecretKey = $GLOBALS['key'];
}
return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $sSecretKey, base64_decode($sValue), MCRYPT_MODE_ECB, mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB), MCRYPT_RAND)));
}
is it possible to get the key which was used when i have a plain key and its hash?
PLAIN: checkingkeyisright
HASH: W0Kdv34iN5Gpkzc4DlisOw4Pynry/O9TLkUq6pwXxY8=
No, it is not. Recovering the key given the ciphertext and plaintext is something which cryptographic ciphers, such as Rijndael, are specifically designed to make infeasible.

error in php crypt

i use such f-n to encrypt\decrypt
<?
//Encrypt Function
function mc_encrypt($encrypt, $mc_key) {
 $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$passcrypt = trim(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
$encode = base64_encode($passcrypt);
return $encode;
}
// Decrypt Function
function mc_decrypt($decrypt, $mc_key) {
$decoded = base64_decode($decrypt);
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB), MCRYPT_RAND);
$decrypted = trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $mc_key, trim($decoded), MCRYPT_MODE_ECB, $iv));
return $decrypted;
}
?>
if i call mc_encrypt('test', 'pass') all decrypts ok, but if i call mc_encrypt('test=value', 'pass') i can't decrypt. why? and what must i do?
You should tell us what happens, i.e. what code you call, what you expect, and what comes out. We cannot guess what "I can't decrypt" means.
I can give you one suggestion already though:
$passcrypt = trim(mcrypt_encrypt(
MCRYPT_RIJNDAEL_256, $mc_key, trim($encrypt), MCRYPT_MODE_ECB, $iv));
Don't mess with the input data [trim($encrypt)]. If the caller wants to trim the string, leave it to them to do it. Otherwise, if your input string has whitespace to trim, you will end up encrypting a different string than was passed in. That can only end in tears.

mcrypt_decrypt return strange code

I tried to encrypt an array then decrypt it back to string by calling a function, it's seem return the correct value if I does all encrypt and decrypt at once time in the function, however, if I return the encrypt value, then call the function again to decrypt it will return me some strange code.
Example 1:
public main()
{
$dataArray = array("one"=>1, "two"=>2, "three"=>3);
$a = $this->encryptDecryptInfo(json_encode($dataArray),$this->key);
var_dump($a);
}
public function encryptDecryptInfo($text,$key)
{
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256,
$text= base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CFB, $iv));
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CFB, $iv);
}
This will return me the correct value which is string(27) "{"one":1,"two":2,"three":3}"
Example 2:
public main()
{
$dataArray = array("one"=>1, "two"=>2, "three"=>3);
$a = $this->encryptDecryptInfo(json_encode($dataArray),$this->key,"encrypt");
$b = $this->encryptDecryptInfo($a,$this->key,"decrypt");
var_dump($b);
}
public function encryptDecryptInfo($text,$key,$type)
{
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
if($type == "encrypt")
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CFB, $iv));
else return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CFB, $iv);
}
However if I do my code in this way, it will return me strange value which is like this string(27) "�ÔérôŸY éXgíœÈÐN*é౜CµÖ" .
Deos anyone know why this is happen? Both encrypt and decrypt coding are the same for example 1 and example 2, but why it will return strange code in example instead? Any way to fix this issue?
I think this is encoding issue look for UTF here - http://php.net/manual/en/function.base64-encode.php in the comments there is a UTF8 safe encoding function.
By passing the parameters left and right you are changing the encoding and you loose it in the translation. Welcome to PHP :)
You must use the same IV for decryption. Just save it along with encrypted data, for example:
if($type == "encrypt") {
$iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CFB), MCRYPT_RAND);
return base64_encode($iv . '##' .
mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CFB, $iv));
} else {
list($iv, $data) = explode('##', base64_decode($text));
return mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CFB, $iv);
}
I had a similar issue. In the database I originally set it up for 16 characters. When I changed to encrypting, I forgot to change that number so the entire encrypted value was not stored. Once I corrected this it returned normal characters :)

Categories