【问题标题】:Decode encoded data in PHP 7.2在 PHP 7.2 中解码编码数据
【发布时间】:2019-12-30 06:06:05
【问题描述】:

我在以前的 PHP 5.6 版本中使用“mcrypt-*”来解码响应,但现在在 PHP 7.2 版本中,因为它已被弃用,我使用的是 openSSL 方法。但它不能正常工作,希望我遗漏了一些东西。

$value="###lllljG5ZOibDGtlL gcQLAtTQUnCJ/bE2glWsL1WKVPdC22c9GtGe/Npx9Uv9IYaszOAVXB4T9s7Hsss/2XpZ9oisx5M4jeV7RK2S/JrBt2E4GEcDGwuJs6NhkKV8hdOcU tmkJLxO3OJ OgVbqrT6a4v5RE7w eP zvQwZyAR5cYCKUYomou9mL/pvfLbe RrBe5ZnMQmUrD6cwUxEE/inikMvIb4K7HI fVPid N B3iPnIYQna6/v9W5A0kslBj6BBDjVXJabwmCSDVxbArm0GDNseWoQAEa4BMxYitqP6cVTxL5Kri8xbAKCW5/unnYnudkHQjNJWW7LuiwDxsBqwQv8D/R/Ff/joFW6q0 muI16/CfIoFnYAyAJWNlKCX9";

    $value = urldecode($value);
    $value = str_replace(" ", "+", $value);

    $abc = triple_decrypt($value);
    print_r($abc);

PHP 5.6 工作正常

function triple_decrypt($input){
    $key = "thisis87658748639testkey";
    $input = base64_decode($input);
    $td = mcrypt_module_open(MCRYPT_TripleDES, "", MCRYPT_MODE_ECB, "");
    $iv = mcrypt_create_iv(mcrypt_enc_get_iv_size ($td), MCRYPT_RAND);
    mcrypt_generic_init($td, $key, $iv);
    $pwd = trim(mdecrypt_generic($td, $input), "\x00..\x0F");
    mcrypt_generic_end($td);
    return $pwd;
}

PHP 7.2

function triple_decrypt($input){
    $key = "thisis87658748639testkey";
    $cipher = "des-ede3";
    $ivlen = openssl_cipher_iv_length($cipher);
    $iv = openssl_random_pseudo_bytes($ivlen);
    $pwd = openssl_decrypt($input, $cipher, $key, $options=0, $iv);
    return $pwd;
}

【问题讨论】:

    标签: php encryption


    【解决方案1】:

    openssl 使用 PKCS7 填充和 mcrypt 零填充 [0][1][2]。要使用 openssl 解密密文,必须禁用 openssl 的填充并且必须删除 mcrypt 的零填充字节:

    function triple_decrypt($input){
        $key = "thisis87658748639testkey";
        $cipher = "des-ede3";
        $decrypted = openssl_decrypt($input, $cipher, $key, $options=OPENSSL_ZERO_PADDING); // Disable openssl's PKCS7-padding
        $unpadded = trim($decrypted, "\x00..\x0F");                                         // Remove mcrypt's Zero-padding bytes
        return $unpadded;
    }
    

    但是,关于加密和解密的重新实现,请注意以下几点:ECB 是一种不安全模式[3]。相反,应该使用 CBC 甚至更好的 GCM [4][5]。推荐使用现代且更快的当今标准 AES [6],而不是 Triple-DES。零填充不可靠,应该应用 PKCS7 填充。


    另外,mcrypt 代码在某种程度上是不一致的:

    • ECB 模式不使用 IV(这也是 openssl_cipher_iv_lengthopenssl 代码 [7] 中返回 0 的原因)。 mcrypt_generic_init 在 ECB 模式 [8] 的情况下会忽略 IV,因此 mcrypt 代码中不使用它,因此 openssl 代码中不需要它。
    • 如果使用需要 IV 的模式,则必须考虑以下问题:加密解密始终需要 IV。因此,在加密期间会生成(并使用)随机 IV,然后将其与密文一起传递给接收者,用于解密。由于 IV 不是秘密,它通常以密文为前缀。因此,在解密期间生成随机 IV 没有任何意义。

    【讨论】:

      【解决方案2】:

      您可以使用openssl()

      function encryptIt($q) {
      
       $cryptKey  = 'YourProjectname'; //any string
      
       $encryptionMethod = "AES-256-CBC"; 
       $secretHash = "25c6c7rr35b9979b151f0205cd13b0vv"; // any hash
      
      //To encrypt
       $qEncoded = openssl_encrypt($q, $encryptionMethod, $secretHash);
      
       return $qEncoded;
      
      }
      
      function decryptIt($q) {
      
       $cryptKey = 'YourProjectname'; //any string
       $encryptionMethod = "AES-256-CBC"; 
       $secretHash = "25c6c7rr35b9979b151f0205cd13b0vv"; // any hash
      
      
      //To Decrypt
       $qDecoded = openssl_decrypt($q, $encryptionMethod, $secretHash);
      
       return $qDecoded;
      
      }
      
      $encryptedstring = encryptIt('TEST');
      echo "<br/>";
      echo decryptIt($encryptedstring); 
      

      【讨论】:

      • 感谢您的快速回复。实际上我已经提到了一个已经解码格式的值($value)。我需要对其进行编码。我能够编码和解码新字符串。
      • ` $ivlen = openssl_cipher_iv_length($cipher);` 返回 0 长度。对于大多数常见的 AES 密码模式(CBC、CFB、ECB、OFB),IV 长度应为 128 位 = 16 字节。
      • 我在加密值中有什么错误或任何问题吗?
      • 更改您的 $cipher = "des-ede3";
      • 我认为 OP 想用 openssl 代码解密密文,而这个密文是 oncemcrypt 加密的i> 代码。因此改变算法/模式是没有意义的。当然,对于重新实现 both(加密和解密)进行更改是有意义的,因为 AES 更快、更现代,而 ECB 通常不安全。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-10
      • 1970-01-01
      • 1970-01-01
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多