Reputation: 4222
Is there some way to generate different output for same given string, here is example:
echo md5('test');
That always generates same fb469d7ef430b0baf0cab6c436e70375
for the given input. How do I generate different encrypted text each time and be able to decrypt it later if needed ?
I have seen functions such as md5
, base64_encode
, crypt
, sha1
, etc but they generate same output and secondly I cannot decrypt later if needed.
P.S: I know I can go with one way encryption and compare encrypted texts but for a particular scenario, I have requirement to be able to decrypt text completely if needed later however I am not able to figure out if there is some way or function in php for it.
Any help will be greatly appreciated. Thanks
Upvotes: 0
Views: 788
Reputation: 4222
I have created this class (Thanks to @Sani Huttunen for the idea) for the purpose. It allows to have differ text generated each time even for same input text and decodes it successfully as well.
class Encoder
{
private static $prefix = '@!@';
public static function php_aes_encrypt($text, $key)
{
if (!trim($text)) {
return '';
}
$iv = self::generateRandomString();
$key = self::mysql_aes_key($key);
$pad_value = 16 - (strlen($text) % 16);
$text = str_pad($text, (16 * (floor(strlen($text) / 16) + 1)), chr($pad_value));
$ciphertext = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$key,
$text,
MCRYPT_MODE_CBC,
$iv
);
$ciphertext = self::getPrefix() . base64_encode($ciphertext . $iv);
return $ciphertext;
}
public static function php_aes_decrypt($text, $key)
{
$text = str_replace(self::getPrefix(), '', $text);
$text = base64_decode($text);
if (!trim($text)) {
return '';
}
$iv = substr($text, -16);
$text = str_replace($iv, '', $text);
$key = self::mysql_aes_key($key);
$text = mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
$key,
$text,
MCRYPT_MODE_CBC,
$iv
);
return rtrim($text, "\0..\16");
}
private static function mysql_aes_key($key)
{
$new_key = str_repeat(chr(0), 16);
for ($i = 0, $len = strlen($key); $i < $len; $i ++) {
$new_key[$i % 16] = $new_key[$i % 16] ^ $key[$i];
}
return $new_key;
}
private static function getPrefix()
{
return base64_encode(self::$prefix);
}
public static function isEncrypted($ciphertext)
{
$isEncrypted = (false !== strpos($ciphertext, self::getPrefix()));
return $isEncrypted;
}
private static function generateRandomString()
{
return substr(sha1(rand()), 0, 16);
}
}
Usage:
$encrypted = Encoder::php_aes_encrypt('my test string', 'key');
echo $encrypted . '<br>';
echo Encoder::php_aes_decrypt($encrypted, 'key');
Upvotes: 0
Reputation: 24385
To encrypt the same plaintext
so that it generates different ciphertext
you change the key (and/or Initialization Vector (IV)
depending on the mode of the algorithm, like CBC).
Example:
$string = 'Some Secret thing I want to encrypt';
$iv = '12345678';
$passphrase = '8chrsLng';
$encryptedString = encryptString($string, $passphrase, $iv);
// Expect: 7DjnpOXG+FrUaOuc8x6vyrkk3atSiAf425ly5KpG7lOYgwouw2UATw==
function encryptString($unencryptedText, $passphrase, $iv) {
$enc = mcrypt_encrypt(MCRYPT_BLOWFISH, $passphrase, $unencryptedText, MCRYPT_MODE_CBC, $iv);
return base64_encode($enc);
}
Both the same IV
and the passphrase
must be used when decrypting in CBC
mode. The passphrase
MUST be kept a secret (from eavesdroppers) while the IV
can be transmitted in the clear.
You CAN (but should not) use the same passphrase
for every message/data but you should ALWAYS change the IV
for each message/data.
This is the basics of encryption but depending on you needs you may need to modify your architecture to keep the system secure.
Upvotes: 1
Reputation: 894
md5 is a hash method, not an encryption.
in short. there is no "good" way back from md5.
base64_encode and base64_decode and be used to transport messages, but it is no decryption.
please google on the topic RSA, ROT-13 or basic encryption with php.
Upvotes: 0