前言:
有一个项目需要跟甲方做接口,甲方使用的是java的3DES加密解密方式。
甲方加密解密部分截图代码:
![](https://i-blog.csdnimg.cn/blog_migrate/4d486dd5b7ab57b50b3e97086b83bba4.png)
第一步:
将甲方的iv转成PHP可以使用的偏移量
![](https://i-blog.csdnimg.cn/blog_migrate/9ff413e71c19881c5ccd55be6fd2c654.png)
第二步:
使用甲方提供的加密程序:输入key和需要加密的字符串
得到加密字符串和解密字符串,留着和PHP7加密解密做对比
![](https://i-blog.csdnimg.cn/blog_migrate/c112f0a7b4155115e4046ecb657c9bcf.png)
第三步:
使用
https://www.tech1024.com/original/2993.html
写的PHP7版的加密解密类库
![](https://i-blog.csdnimg.cn/blog_migrate/36487670e7bb45aa6adb482117ffc0eb.png)
得到的结果一样。
代码:
class Des
{
public static function encrypt($input, $key, $method = 'DES-ECB', $iv = null)
{
$iv = $iv ? $iv : self::createIv();
return base64_encode(openssl_encrypt($input, $method, $key, OPENSSL_RAW_DATA, $method == 'DES-ECB' ? '' : $iv));
}
public static function decrypt($input, $key, $method = 'DES-ECB', $iv = null)
{
$iv = $iv ? $iv : self::createIv();
return openssl_decrypt(base64_decode($input), $method, $key, OPENSSL_RAW_DATA, $method == 'DES-ECB' ? '' : $iv);
}
public static function createIv()
{
return self::hexToStr("0000000000000000");
}
public static function hexToStr($hex)
{
$string = '';
for ($i = 0; $i < strlen($hex) - 1; $i += 2) {
$string .= chr(hexdec($hex[$i] . $hex[$i + 1]));
}
return $string;
}
}
$str = 'helloworld';
$key = '123456781234567812345678';
$iv = pack('H*','1234567890abcdef');
echo Des::encrypt($str,$key,'DES-EDE3-CBC',$iv);
echo PHP_EOL;
$str = 'wR/xa+1PN1E8vkWeDr//Dw==';
echo Des::decrypt($str,$key,'DES-EDE3-CBC',$iv);
其他:
php7以下的装mcrypt扩展,也是可以实现的,网上找的DES类库,代码将贴在下面
![](https://i-blog.csdnimg.cn/blog_migrate/452d6bf41242084c769cb6dd5df61262.png)
得到的结果也一样
代码:
class Des
{
private static $_instance = NULL;
var $key;//秘钥向量
var $iv;//混淆向量 ->偏移量
function __construct()
{
$this->key = '123456781234567812345678';
//$this->iv = pack('H*','185286120-112-85-51-17');
//$this->iv = '1234567890abcdef';
$this->iv = pack('H*','1234567890abcdef');
}
public static function share()
{
if (is_null(self::$_instance)) {
self::$_instance = new Des();
}
return self::$_instance;
}
function encrypt($input)
{
//获得加密算法的分组大小 8
$size = mcrypt_get_block_size(MCRYPT_DES, MCRYPT_MODE_CBC); //3DES加密将MCRYPT_DES改为MCRYPT_3DES
//ascii 填充
$input = $this->pkcs5_pad($input, $size); //如果采用PaddingPKCS7,请更换成PaddingPKCS7方法。
//用0填充秘钥为指定长度8
$key = str_pad($this->key, 8, '0'); //3DES加密将8改为24
//打开算法和模式对应的模块
$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');
//判断混淆向量是否为空
if ($this->iv == '') {
//从算法源随机生成混淆向量
$iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);//类似b"¨ß^\f\x1EÅ╩5"
} else {
//反之取设置的混淆向量
$iv = $this->iv;
}
//初始化加密所需的缓冲区
@mcrypt_generic_init($td, $key, $iv);
//加密数据 $td为算法对象模块 $input为处理过后的值
$data = mcrypt_generic($td, $input);// 类似b"ýyP\x7FN\x00èiÝd>À?s\x18Î"
//对加密模块进行清理工作
mcrypt_generic_deinit($td);
//关闭加密模块
mcrypt_module_close($td);
//使用 MIME base64 对数据进行编码
$data = base64_encode($data);//如需转换二进制可改成 bin2hex 转换
//如果设置了混淆向量 则加密的值是固定的 如果没设置混淆向量 则加密的值是随机的
return $data;
}
function decrypt($encrypted)
{
//对使用 MIME base64 编码的数据进行解码
$encrypted = base64_decode($encrypted); //如需转换二进制可改成 bin2hex 转换
//使用另一个字符串填充字符串为指定长度 获取秘钥
$key = str_pad($this->key, 8, '0'); //3DES加密将8改为24
//打开算法和模式对应的模块
$td = mcrypt_module_open(MCRYPT_DES, '', MCRYPT_MODE_CBC, '');//3DES加密将MCRYPT_DES改为MCRYPT_3DES
//判断混淆向量是否为空
if ($this->iv == '') {
//从算法源随机生成混淆向量
$iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
} else {
//反之取设置的混淆向量
$iv = $this->iv;
}
//返回打开的模式所能支持的最长密钥 没用上
$ks = mcrypt_enc_get_key_size($td);//DES 8 3DES 24
//初始化加密所需的缓冲区
@mcrypt_generic_init($td, $key, $iv);
//解密数据 $td为算法对象模块 $encrypted为需要解密的数据
$decrypted = mdecrypt_generic($td, $encrypted);//类似于 "15549070665\x05\x05\x05\x05\x05" 之前加密的数据
//对加密模块进行清理工作
mcrypt_generic_deinit($td);
//关闭加密模块
mcrypt_module_close($td);
//返回取出解密数据
$data = $this->pkcs5_unpad($decrypted);
return $data;
}
function pkcs5_pad($text, $blocksize)
{
//$pad=5 blocksize=11 $test=8 %取余
$pad = $blocksize - (strlen($text) % $blocksize);//5
//返回ascii填补后的字符串, 类似 "15549070665\x05\x05\x05\x05\x05"
return $text . str_repeat(chr($pad), $pad);
}
function pkcs5_unpad($text)
{
//取出最后一个字符串 {15} ord返回字符的 ASCII 码值
$pad = ord($text{strlen($text) - 1});//5
//判断$pad的值是否大于本身字符串
if ($pad > strlen($text)) {
//如果大于 则多余
return false;
}
//计算ASCII 码值中全部字符都存在于$text字符集合中的第一段子串的长度是否等于取出的$pad
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
//如果不相等 则缺失
return false;
}
//返回字符串的子串
return substr($text, 0, -1 * $pad);
}
function PaddingPKCS7($data)
{
$block_size = mcrypt_get_block_size(MCRYPTDES, MCRYPT_MODE_CBC);//3DES加密将MCRYPT_DES改为MCRYPT_3DES
$padding_char = $block_size - (strlen($data) % $block_size);
$data .= str_repeat(chr($padding_char), $padding_char);
return $data;
}
private function UnPaddingPKCS7($text)
{
$pad = ord($text{strlen($text) - 1});
if ($pad > strlen($text)) {
return false;
}
if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
return false;
}
return substr($text, 0, -1 * $pad);
}
}
echo (new Des())->encrypt('helloworld');
echo PHP_EOL;
echo (new Des())->decrypt('wR/xa+1PN1E8vkWeDr//Dw==');