发现一个关于openssl_encrypt加密解密的问题,不知道是不是bug,哪位大神帮忙解答一下
//PHP Version 8.1.6 //Build Date May 11 2022 08:52:54 //Compiler Visual C++ 2019 //Thread API Windows Threads class Crypt { public $cipher_algo = "aes-128-ccm"; //加密方法 public $passphrase = 'qw7%!^O'; //加密密钥 public $options = 0; //数据格式选项(可选) public $iv = '-_)+^miwz]O#'; //加密初始化向量(可选) public $tag = ''; public function encrypt($data): string { return openssl_encrypt($data, $this->cipher_algo, $this->passphrase, $this->options, $this->iv, $this->tag); } public function decrypt($data): string { return openssl_decrypt($data, $this->cipher_algo, $this->passphrase, $this->options, $this->iv, $this->tag); } } $crypt = new Crypt(); function encrypt(): string { $crypt = new Crypt(); $now = date("Y-m-d H:i:s"); $encrypt = $crypt->encrypt(md5($now) . '@' . $now); return base64_encode($encrypt); } $token = encrypt(); $base64_decode = base64_decode($token); $decrypt = $crypt->decrypt($base64_decode); echo '第一次《br/》'; echo "token=" . $token . '《br/》'; echo "base64_decode=" . $base64_decode . '《br/》'; echo "decrypt=" . $decrypt . '《br/》'; echo '解密失败?《br/》《br/》《br/》'; $now = date("Y-m-d H:i:s"); $encrypt = $crypt->encrypt(md5($now) . '@' . $now); $csrf = base64_encode($encrypt); echo '第二次《br/》'; $token = $csrf; $base64_decode = base64_decode($token); $decrypt = $crypt->decrypt($base64_decode); echo "token=" . $token . '《br/》'; echo "base64_decode=" . $base64_decode . '《br/》'; echo "decrypt=" . $decrypt . '《br/》'; echo '解密成功';
获得的结果长这个样子
第一次 token=dGk2d1o1WnNIcm5ZQ3RIWlJYWVRLY3QxeXloZk1mNThpOFZ4bzVnM2l3V3F5blJhcGtnTkk3OWY0cHkxMzdsQ1UwWDdoQT09 base64_decode=ti6wZ5ZsHrnYCtHZRXYTKct1yyhfMf58i8Vxo5g3iwWqynRapkgNI79f4py137lCU0X7hA== decrypt= 解密失败? 第二次 token=dGk2d1o1WnNIcm5ZQ3RIWlJYWVRLY3QxeXloZk1mNThpOFZ4bzVnM2l3V3F5blJhcGtnTkk3OWY0cHkxMzdsQ1UwWDdoQT09 base64_decode=ti6wZ5ZsHrnYCtHZRXYTKct1yyhfMf58i8Vxo5g3iwWqynRapkgNI79f4py137lCU0X7hA== decrypt=57869668d9ac3ec22eda6afd9447069f@2023-07-16 09:12:54 解密成功
第一次加密解密与第二次的区别是,第一次使用函数返回加密内容,而第二次直接把加密过程代码写在过程里,有哪位大神能看出问题吗?虚心请教一下原因。谢谢!
本作品采用《CC 协议》,转载必须注明作者和本文链接
因为调用解密方法的对象和加密的对象不是同一个。
第一次对象调用加密方法是在函数内完成的,解密的时候应该也使用该对象,因为在调用加密方法的时候会生成tag赋值给对象内的属性,tag在解密的时候也会用到,所以第一次调用解密失败了。加密的时候,参数tag是引用,会赋值,解密的时候会用到