PHP 之对称加密TDEA(3DES) 使用 可以用于SSO 等的校验

分类:PHP |

有时候我们需要对数据进行加密, 但也需要对数据进行完整解密, 这时就需要可还原的加密方式, 对称加密是最佳选择了: 

这里选择了TDEA ( 3DES )


<?php

/**
 * @author Primo Cheng
 * 3DES加密算法,可以使用PKCS7填充
 * @example
 * $d = tripledes();
 * $str = '1234756%3WEWEddd';
 * 加密:$en = $d->encrypt($str);
 * 解密:$de = $d->decrypt($en);
 *
 */
defined('MCRYPT_3DES_KEY') or define('MCRYPT_3DES_KEY', 'IAMTHEKEY');
defined('MCRYPT_3DES_IV') or define('MCRYPT_3DES_IV', 'IMIV3DES');

class threeDes {
        // 私钥
        private $_key = MCRYPT_3DES_KEY;
        // 初始化向量,只有CBC模式下需要iv,其他模式下iv会被忽略
        private $_iv = MCRYPT_3DES_IV;
        // 填充模式
        private $_paddingModel = 'PKCS7';

        /**
         * 这里接收的$_key是24位,$_iv是8位
         * 如果位数不对需要转换
         */
        public function __construct() {
                //convert to 8 bit
                switch (strlen($this->_iv)) {
                        case 16 :
                                $this->_iv = pack('H16', $this->_iv);
                                break;
                        case 12 :
                                $this->_iv = base64_decode($this->_iv);
                                break;
                }
                //convert to 24 bit
                switch (strlen($this->_key)) {
                        case 48 :
                                $this->_key = pack('H48', $this->_key);
                                break;
                        case 32 :
                                $this->_key = base64_decode($this->_key);
                                break;
                }
        }

        /**
         * 加密
         */
        public function encrypt($value) {
                $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
                $value = $this->_padding($value); // 填充
                mcrypt_generic_init($td, $this->_key, $this->_iv);
                $ret = base64_encode(mcrypt_generic($td, $value));
                mcrypt_generic_deinit($td);
                mcrypt_module_close($td);

                return $ret;
        }

        /**
         * 解密
         */
        public function decrypt($value) {
                $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
                mcrypt_generic_init($td, $this->_key, $this->_iv);
                $ret = trim(mdecrypt_generic($td, base64_decode($value)));
                $ret = $this->_unpadding($ret);
                mcrypt_generic_deinit($td);
                mcrypt_module_close($td);
                return $ret;
        }

        /**
         * 填充
         */
        private function _padding($data) {
                if (empty($this->_paddingModel)) {
                        return $data;
                }
                switch ($this->_paddingModel) {
                        case 'PKCS7' :
                                $block = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_ECB);
                                $pad = $block - (strlen($data) % $block);
                                if ($pad <= $block) {
                                        $char = chr($pad);
                                        $data .= str_repeat($char, $pad);
                                }
                                return $data;
                        default :
                                return $data;
                }
        }

        /**
         * 清除填充
         */
        private function _unpadding($data) {
                if (empty($this->_paddingModel)) {
                        return $data;
                }
                switch ($this->_paddingModel) {
                        case 'PKCS7' :
                                $padlen = ord(substr($data, (strlen($data) - 1), 1));
                                if ($padlen > 8)
                                        return $data;

                                for ($i = -1 * ($padlen - strlen($data)); $i < strlen($data); $i++) {
                                        if (ord(substr($data, $i, 1)) != $padlen)
                                                return false;
                                }

                                return substr($data, 0, -1 * ($padlen - strlen($data)));

                        default :
                                return $data;
                }
        }

}



$x = new threeDes();
$enstr = $x->encrypt('http://www.updateweb.cn');
print_r($enstr);
echo "\n";

$originstr = $x->decrypt('+hop8jhWPrNRnwwQFWTzwjnf/OU5KJ5P');
print_r($originstr);
echo "\n";

执行结果如下:

image.png