I'm using a function to encode and decode some text ,
But seems it doesn't support my country language (Persian) and change them to some unreadable text, How can i fix it .
<?php
class encrypt {
/********* Encode *********/
public static function encode($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, md5(base64_encode(trim($encryption_key))), utf8_encode(trim($pure_string)), MCRYPT_MODE_ECB, $iv);
return base64_encode($encrypted_string);
}
/********** Decode ************ */
public static function decode($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, md5(base64_encode(trim($encryption_key))),base64_decode(trim($encrypted_string)), MCRYPT_MODE_ECB, $iv);
return $decrypted_string;
}
}
?>
The same IV needs to be used for encryption and decryption, a general method is to prefix the encrypted data with the IV for use during decryption.
There is no need to Base64 encode or trim the encryption key.
Do not trim the encrypted data, encrypted data can contain null (0x00) bytes.
Encryption operates on bytes, not characters, as such any text language makes no difference.
Adding calls inline to other calls just makes debugging more difficult, separate the steps into separate statements with intermediate variables.
Do not use Blowfish, use AES, even the creator of Blowfish uses AES.
Do not use ECB mode, it is insecure, see ECB mode, scroll down to the Penguin.
ECB mode does not use an IV.
What you are doing is encryption, not encoding.
Consider using defuse or RNCryptor, they provide a complete solution and are being maintained.
Related
the encryption in the front end works but the decryption in the backend does not work.
I am using crypto JS for the front end and PHP in the back end. And I want to use AES-256
<script>
function encrypt(){
passphrase= "123456";
encrypted = CryptoJS.AES.encrypt("decrypted soon", passphrase);
return encrypted;
}
</script>
in PHP
public function decrypt ($encrypted)
{
$passphrase= "123456";
$encrypted = base64_decode($encrypted);
$decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', $key, OPENSSL_RAW_DATA);
return trim($decrypted);
}
Your help is much appreciated
I am implementing a reversible encryption algorithm based on an example at http://www.edzynda.com/create-a-self-destructing-encrypted-message-app-in-laravel-part-1/
I have put the code inside a model event function:
public static function boot()
{
parent::boot();
// Setup event bindings...
static::creating(function($account)
{
/* encrypt password and save iv */
$encryption = self::encrypt($account->db_password); // or: Input::get('db_password')
$account->db_password = $encryption['encrypted_string'];
$account->iv = $encryption['iv'];
Log::debug($account);
//print_r ($encryption);
});
}
public static function encrypt($string)
{
// Generate an IV
$iv_size = mcrypt_get_iv_size(MCRYPT_BLOWFISH, MCRYPT_MODE_CFB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_DEV_URANDOM);
// Encrypt the string
$encrypted_string = mcrypt_encrypt(MCRYPT_BLOWFISH, $_ENV['ACCOUNT_KEY'], $string, MCRYPT_MODE_CFB, $iv);
return ['encrypted_string' => $encrypted_string, 'iv' => $iv];
}
In my database seeder, I am calling Model::create to make the string is encrypted before saving. This is called from my tests. However, I am getting
[ErrorException]
json_encode(): Invalid UTF-8 sequence in argument
I've made sure that the column type is binary.
Extra info: when I perform mb_detect_encoding on either value ($iv or $string) I get either UTF-8, or nothing, I guess depending not the random characters that appear in the result.
My solution: for storage and transportation, the encrypted string and IV need to be base64 encoded.
The relevant line above changed to:
return [
'encrypted_string' => base64_encode($encrypted_string),
'iv' => base64_encode($iv)
];
and of course base64_decode must be used before decrypting the string with the stored IV value.
These days I read a lot here on SO about password hashing and data encryption. It's a real mess, I mean, deciding what the best practice is. I need a very simple class that can be reused anywhere and that provide a decent-but-not-paranoic security level for my PHP applications (I do not handle bank data). Additionally, I want to rely as much as possible on PHP standard libs. I came up with this:
class Security {
public static function hashPassword($plain) {
$salt = md5(rand(0, 1023) . '#' . time()); // Random salt
return crypt($plain, '$2a$07$' . $salt); // '$2a$07$' is the Blowfish trigger
}
public static function checkPassword($plain, $hash) {
return (crypt($plain, $hash) === $hash);
}
public static function generateIv() {
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC); // It's 32
return mcrypt_create_iv($iv_size, MCRYPT_RAND);
}
public static function encrypt($key, $data, $iv = null, $base64 = true) {
if (is_null($iv)) $iv = md5($key);
$ret = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_CBC, $iv);
return ($base64 ? base64_encode($ret) : $ret);
}
public static function decrypt($key, $data, $iv = null, $base64 = true) {
if (is_null($iv)) $iv = md5($key);
return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $base64 ? base64_decode($data) : $data, MCRYPT_MODE_CBC, $iv), "\0");
}
}
As you can see, I choose to hash passwords with crypt() using Blowfish hashing algorithm. The return value of hashPassword() is the salt + hash that then I store in the DB. I made this choice because crypt() is available on every server, provides a confortable way to check hash regardless of algorithm used (it's based on salt prefix) and, I read, bcrypt is a decent hashing method.
Then, for data encryption I used mcrypt() Rijndael 256 algorithm with CBC mode. As you can see, I can use encryption methods in two way. I can pass a IV (and generateIv() helps me to create one) that I will store in the DB along crypted data, or, if I don't, a basic IV is derived from key in both crypt and decrypt process.
What do you think about it? Am I missing something? Can I be finally relaxed about hashing and encryption in my PHP aplications?!?
You are using Rijndael 256 bit encryption, which is not AES standard. Try to use AES (MCRYPT_RIJNDAEL_128) using 256 bit keys instead.
A random IV should be kept with cipher text if the derived key is also used to encrypt other data.
You are using out of date functions, you might want to use bcrypt and SHA-256 for the IV (only use the 16 - blocksize - left most bytes) .
Note that this list may not be complete.
i have a little problem: my decryption won't give me the same string i encoded, and i can't find the problem... looked in other posts, but nothing helpful there
here are my functions:
public static function encryptData($data){
if($key = self::getEncryptionKey()){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $data, MCRYPT_MODE_ECB,$iv));
} else {
return false;
}
}
public static function decryptData($data)
{
if($key = self::getEncryptionKey()){
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($data), MCRYPT_MODE_ECB,$iv);
} else {
return false;
}
}
where's the problem? i'm kinda desperate here...
To decrypt you need everything exactly the same at both sides. key, mode, IV and padding.
Looking at your code, you appear to be generating a new IV for decryption. Don't. Use the same IV as you used to encrypt.
You, correctly, specify a mode explicitly, but you pick the worst possible mode. Don't use ECB, it leaks information. Use CBC or CTR mode instead.
You don't specify a padding. Far better to specify it explicitly, use PKCS7 with Rijndael.
If none of that helps, then check your key, byte by byte, to make sure it is the same for both encryption and decryption.
I have a problem with CBC mode when I try to encrypt/decrypt some text using php's mcrypt extension. I've created a class to perform this operations, it works fine with other modes but CBC.
The problem is as follow:
I use the clear text Even in cryptography, silence is golden. I do the encryption part, no problem till this point. But each time I try to decrypt, I get something like this: 9��'t"�cryptography, silence is golden. As you can see, the first 8 characters of the text are wrong. I don't know what may be causing this behavior.
The parts of my class which handle these operations are:
public function encrypt($data)
{
$cypher = $this->_getCypher();
$iv = $this->_getIv($cypher);
return trim(base64_encode(mcrypt_encrypt($cypher, self::KEY, $data, MCRYPT_MODE_CBC, $iv)));
}
public function decrypt($data)
{
$cypher = $this->_getCypher();
$iv = $this->_getIv($cypher);
return trim(mcrypt_decrypt($cypher, self::KEY, base64_decode($data), MCRYPT_MODE_CBC, $iv));
}
protected function _getCypher()
{
return self::$_cyphers[$this->_algorithm];
}
protected function _getIv($cypher)
{
return mcrypt_create_iv(mcrypt_get_iv_size($cypher, MCRYPT_MODE_CBC), MCRYPT_RAND);
}
And the algorithm used for above example is 3DES. As I said before, using other mode, such as ECB, everything works fine.
Any suggestions ?
You need to remember the IV that you used for encryption and use that again for decryption.