【问题标题】:3DES PHP Encryption Not Decrypting Properly3DES PHP 加密未正确解密
【发布时间】:2014-03-21 17:33:42
【问题描述】:

我正在使用以下代码对将在链接 URL 末尾传递到外部站点的信息进行加密。现在它能够自己进行加密和解密,但是当我去在线解密器(online-domain-tools.com,tools4noobs.com)时,我看到添加了额外的符号,或者它没有显示任何正确的内容。当然我是新手。我有什么,我从其他问题(php-equivalent-for-java-triple-des-encryption-decryption,php-equivalent-encryption-decryption-tripledes,php-encrypt-decrypt-with-tripledes-pkcs7-and-ecb)拼凑而成。感谢您的任何帮助或指导!

我只能将 3DES 与 CBC 一起使用。

PHP 代码:

$key = "12AB12AB12AB12AB12AB12AB";
$iv = "12AB12AB";
$cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');

// MESSAGE
$message = "email=billysmith@afakeemail.com&account=987654321&role=2";
echo 'Message:::  ' .$message .'<br />';

// ENCRYPTED
$encrypted = Encryptor($message);
echo 'Encrypted:::  ' .$encrypted .'<br />';

// DECRYPTED
$decrypted = Decryptor($encrypted);
echo 'Decrypted:::  ' .$decrypted .'<br />';

function Encryptor($buffer) {
  global $key, $iv, $cipher;

  // get the amount of bytes to pad
  $extra = 8 - (strlen($buffer) % 8);

  // add the zero padding
  if($extra > 0) {
    for($i = 0; $i < $extra; $i++) {
      $buffer .= "\0";
    }
  }
  mcrypt_generic_init($cipher, $key, $iv);
  $result = bin2hex(mcrypt_generic($cipher, $buffer));
  mcrypt_generic_deinit($cipher);
  return $result;
}

function Decryptor($buffer) {
  global $key, $iv, $cipher;

  mcrypt_generic_init($cipher, $key, $iv);
  $result = rtrim(mdecrypt_generic($cipher, hex2bin($buffer)), "\0");
  mcrypt_generic_deinit($cipher);
  return $result;
}

function hex2bin($data)
{
  $len = strlen($data);
  return pack("H" . $len, $data);
} 

【问题讨论】:

    标签: php security encryption 3des tripledes


    【解决方案1】:

    简而言之:您的代码是正确的。您无法使用提供的工具测试您的加密。

    这两个工具都不允许输入您的 IV。

    IV 应该是唯一的并且可以公开转移。

    通过解码使用错误的IV会在解密数据的开头给出错误的部分。

    这里是面向对象的版本。它使用零填充(内置于 PHP),就像您的代码一样。如果原始消息已经对齐,它也不会填充**。

    <?php
    
    $key = "12AB12AB12AB12AB12AB12AB";
    $iv = "12AB12AB";
    
    // MESSAGE
    $message = "email=billysmith@afakeemail.com&account=987654321&role=22";
    echo 'Message:::   ' . $message . PHP_EOL;
    
    
    $cryptor = new Crypt3Des();
    
    $encryptedMessage = $cryptor->encrypt($message, $key, $iv);
    echo 'Encrypted:::  ' . bin2hex($encryptedMessage) . PHP_EOL;
    
    $decryptedMessage = $cryptor->decrypt($encryptedMessage, $key, $iv);
    echo 'Decrypted:::  ' . $decryptedMessage . PHP_EOL;
    
    class Crypt3Des
    {
        private $cipher;
    
        public function __construct()
        {
            $this->cipher = mcrypt_module_open(MCRYPT_3DES, '', 'cbc', '');
        }
    
        public function encrypt($data, $key, $iv)
        {
            mcrypt_generic_init($this->cipher, $key, $iv);
            $result = mcrypt_generic($this->cipher, $data);
            mcrypt_generic_deinit($this->cipher);
            return $result;
        }
    
        public function decrypt($encryptedData, $key, $iv)
        {
            mcrypt_generic_init($this->cipher, $key, $iv);
            $result = mdecrypt_generic($this->cipher, $encryptedData);
            mcrypt_generic_deinit($this->cipher);
            $result = rtrim($result, "\0");
            return $result;
        }
    }
    
    
    // Before 5.4.0
    if (!function_exists('hex2bin')) {
        function hex2bin($data)
        {
            $len = strlen($data);
            return pack("H" . $len, $data);
        }
    }
    

    【讨论】:

    • 所以没有办法在不让他们实际运行测试的情况下测试外部解密它的人吗?我使用在线资源的原因是因为这将是第 3 方,我想确保(我看起来不像傻瓜)他们能够最终解密它。因此,只要它们的解密器的 IV 相同,前面的文本就会正确显示?
    • 当然可以!我刚刚找到了一个带有正确测试工具的站点:link 它提供了相同的输出,您的代码可以
    • 好吧,只要密钥的长度合适,它就不会使用任何正确的填充?
    • 不,我的意思是消息填充(零填充)。只要您的消息中只有文本加载,它就可以工作,但不能用于二进制数据。
    • 对于这个项目来说,它只是文本。现在,对于每次加密,它将仅使用电子邮件、帐户 # 和角色 # 信息。如果我使用二进制数据,有什么更好的填充方法?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 2012-11-20
    • 1970-01-01
    • 2016-01-27
    • 2015-11-02
    • 2015-06-19
    相关资源
    最近更新 更多