PHP 之对称加密TDEA(3DES) 使用 可以用于SSO 等的校验
有时候我们需要对数据进行加密, 但也需要对数据进行完整解密, 这时就需要可还原的加密方式, 对称加密是最佳选择了:
这里选择了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";
执行结果如下:
