【问题标题】:php: how to generate different output for same stringphp:如何为相同的字符串生成不同的输出
【发布时间】:2014-09-29 13:35:51
【问题描述】:

有没有办法为相同的给定字符串生成不同的输出,这里是例子:

echo md5('test');

这总是为给定的输入生成相同的fb469d7ef430b0baf0cab6c436e70375。如何每次生成不同的加密文本并在需要时进行解密?

我见过md5base64_encodecryptsha1 等函数,但它们会产生相同的输出,其次,如果需要,我以后无法解密。

P.S:我知道我可以使用一种方式加密并比较加密文本,但对于特定情况,我需要能够在以后需要时完全解密文本但是我无法弄清楚是否有某种方式或在 php 中为它提供函数。

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

【问题讨论】:

  • 如果您可以再次将哈希恢复到原始状态,那么哈希的意义何在
  • 您将encryption 算法与hash 算法混淆了。 MD5SHA1one-way hash 算法,并不意味着“解密”。您应该使用encryption 算法,例如3DESAESTwoFish 等。
  • md5sha1不是加密函数,它们是散列算法,它们的全部意义在于它们'仅单向。好的哈希不能“解密”
  • @SaniHuttunen:抱歉,是的,我希望能够加密给定文本并稍后解密,但条件是即使对于相同的给定字符串,加密文本也应该不同。
  • @EliasVanOotegem:然后使用encryption 算法。每个算法将采用key(您可以随机定义或选择)。这个key 用于加密数据和解密数据。如果您使用不同的keys,相同的plaintext 将导致不同的ciphertext

标签: php string encryption random


【解决方案1】:

要加密相同的plaintext 使其生成不同的ciphertext,您需要更改密钥(和/或Initialization Vector (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 模式下解密时必须使用相同的IVpassphrasepassphrase 必须保密(防止窃听者),而 IV 可以明文传输。

您可以(但不应该)对每个消息/数据使用相同的 passphrase,但您应该始终为每个消息/数据更改 IV

这是加密的基础知识,但根据您的需要,您可能需要修改架构以确保系统安全。

【讨论】:

  • $iv 值应始终为 8 个字符长?因为如果我增加它,我会得到块大小相同的错误
  • @Dev01:IV 必须始终与算法的block size 长度相同。在这种情况下,block size 为 64 位(8 个字符)。
  • 如果您可以生成并预先添加一个随机 IV 并在您的代码中使用 AES (MCRYPT_RIJNDAEL_128),我会对此表示赞同。
  • 将此答案标记为正确,因为它给出了这个想法。我已经为此目的创建了一个类,如我的答案所示。
【解决方案2】:

md5 是一种哈希方法,而不是一种加密方法。

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

base64_encode 和base64_decode 用于传输消息,但它没有解密。

请搜索有关 RSA、ROT-13 或 php 基本加密的主题。

【讨论】:

    【解决方案3】:

    为此目的,我创建了这个类(感谢@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);
        }
    }
    

    用法:

    $encrypted = Encoder::php_aes_encrypt('my test string', 'key');
    echo $encrypted . '<br>';
    echo Encoder::php_aes_decrypt($encrypted, 'key');
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 1970-01-01
      • 2016-08-17
      • 1970-01-01
      • 2016-05-22
      相关资源
      最近更新 更多