Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php:如何为同一字符串生成不同的输出_Php_String_Encryption_Random - Fatal编程技术网

php:如何为同一字符串生成不同的输出

php:如何为同一字符串生成不同的输出,php,string,encryption,random,Php,String,Encryption,Random,是否有某种方法可以为同一给定字符串生成不同的输出,例如: echo md5('test'); 它总是为给定输入生成相同的fb469d7ef430b0baf0cab6c436e70375。如何每次生成不同的加密文本,并在需要时在以后解密 我见过诸如md5、base64_encode、crypt、sha1等函数,但它们生成相同的输出,其次,如果需要,我以后无法解密 注:我知道我可以使用单向加密并比较加密文本,但对于特定场景,我需要能够在以后需要时完全解密文本,但我无法确定php中是否有某种方法或函

是否有某种方法可以为同一给定字符串生成不同的输出,例如:

echo md5('test');
它总是为给定输入生成相同的
fb469d7ef430b0baf0cab6c436e70375
。如何每次生成不同的加密文本,并在需要时在以后解密

我见过诸如
md5
base64_encode
crypt
sha1
等函数,但它们生成相同的输出,其次,如果需要,我以后无法解密

注:我知道我可以使用单向加密并比较加密文本,但对于特定场景,我需要能够在以后需要时完全解密文本,但我无法确定php中是否有某种方法或函数用于此


任何帮助都将不胜感激。谢谢

md5是一种散列方法,而不是加密方法

简而言之。从md5返回没有“好”的方法

base64_编码和base64_解码并用于传输消息,但它不是解密


请用谷歌搜索主题RSA、ROT-13或php基本加密。

要加密相同的
明文
,使其生成不同的
密文
,请更改密钥(和/或
初始化向量(IV)
,具体取决于算法的模式,如CBC)

例如:

$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); 
}
CBC
模式下解密时,必须使用相同的
IV
passphrase
passphrase
必须保密(防止窃听者),而
IV
可以透明传输

您可以(但不应该)对每条消息/数据使用相同的
密码短语
,但您应该始终更改每条消息/数据的
IV

这是加密的基础,但根据您的需要,您可能需要修改您的体系结构以保持系统的安全。

为此,我创建了这个类(感谢@Sani Huttunen)。它允许每次生成不同的文本,即使是相同的输入文本,也能成功解码

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);
    }
}
类编码器
{
私有静态$prefix='@!@';
公共静态函数php_aes_encrypt($text,$key)
{
如果(!修剪($text)){
返回“”;
}
$iv=self::generateRandomString();
$key=self::mysql\u aes\u key($key);
$pad_value=16-(strlen($text)%16);
$text=str_pad($text,(16*(楼层(strlen($text)/16)+1)),chr($pad_值));
$ciphertext=mcrypt\u加密(
MCRYPT_RIJNDAEL_128,
$key,
$text,
MCRYPT_模式_CBC,
四美元
);
$ciphertext=self::getPrefix().base64_encode($ciphertext.$iv);
返回$ciphertext;
}
公共静态函数php_aes_decrypt($text,$key)
{
$text=str_replace(self::getPrefix(),“”,$text);
$text=base64_解码($text);
如果(!修剪($text)){
返回“”;
}
$iv=子字符串($text,-16);
$text=str_替换($iv,,$text);
$key=self::mysql\u aes\u key($key);
$text=mcrypt\u解密(
MCRYPT_RIJNDAEL_128,
$key,
$text,
MCRYPT_模式_CBC,
四美元
);
返回rtrim($text,“\0..\16”);
}
私有静态函数mysql\u aes\u key($key)
{
$new_key=str_repeat(chr(0),16);
对于($i=0,$len=strlen($key);$i<$len;$i++){
$new_key[$i%16]=$new_key[$i%16]^$key[$i];
}
返回$new_密钥;
}
私有静态函数getPrefix()
{
返回base64_编码(self::$prefix);
}
已加密公共静态函数($ciphertext)
{
$isEncrypted=(false!==strpos($ciphertext,self::getPrefix());
返回$i加密;
}
私有静态函数GeneratorDomainString()
{
返回substr(sha1(rand()),0,16);
}
}
用法:

$encrypted = Encoder::php_aes_encrypt('my test string', 'key');
echo $encrypted . '<br>';
echo Encoder::php_aes_decrypt($encrypted, 'key');
$encrypted=Encoder::php_aes_encrypt('my test string','key');
echo$已加密。”
'; echo编码器::php_aes_decrypt($encrypted,'key');
hash的意义是什么?如果你能将其恢复到原始状态,你就把
加密
算法与
hash
算法混淆了
MD5
SHA1
单向散列算法
,并不意味着要“解密”。你应该使用
加密
算法,比如
3DES
AES
TwoFish
,等等。
md5
sha1
不是加密函数,它们是散列算法,它们的全部要点是它们只是单向的。好的散列不能被“解密”@SaniHuttunen:哦,很抱歉,是的,我希望能够对给定的文本进行加密并在以后解密,但条件是即使对于相同的给定字符串,加密的文本也应该不同。@EliasVanOotegem:然后使用
加密
算法。每个算法将使用一个
(您可以定义或随机选择)。此
密钥
用于对数据进行加密和解密。如果使用不同的
,相同的
明文
将导致不同的
密文
。$iv值应始终为8个字符长?因为如果我增加它,我会得到blocksize的误差same@Dev01:
IV
必须始终与算法的
块大小
具有相同的长度。在本例中,
块大小为64位(8个字符)。如果您可以生成并预编一个随机IV,并在代码中使用AES(
MCRYPT_RIJNDAEL_128
),我将对此进行改进。将此答案标记为正确的原因,这就给出了想法。我已经为此创建了一个类,如我的答案所示。