PHP云闪付小程序手机号3DES解密
云闪付获取手机号等敏感信息是经过3DES/ECB加密的,文档上给的解密方法是JAVA的,PHP无法使用,这里是偶然间发现的解密方法,经过修改可以解密出来。
但是mcryp等相关方法已在PHP7.1.0之后废弃了,高版本PHP使用时需要安装扩展
上代码:
<?php
namespace upsdk\kit;
/**
* 3DES
* Class Encrypt
* @package upsdk\kit
*/
class TripleEncrypt
{
/**
* 加密
* @param $input
* @param $key
* @param string $iv
* @return string
*/
public static function encrypt3DES($input, $key, $iv = "12345678910111213")
{
$key = pack("H*", $key);
$iv = pack("H*", $iv);
$input = self::addPKCS7Padding($input);
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, $iv);
$data = mcrypt_generic($td, $input);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$data = self::removeBR(base64_encode($data));
//$data= iconv("UTF-8","GB2312//IGNORE",$data);
return $data;
}
/**
* 加密
* @param $source
* @return string
*/
private static function addPKCS7Padding($source)
{
$block = mcrypt_get_block_size('tripledes', 'cbc');
$pad = $block - (strlen($source) % $block);
if ($pad <= $block) {
$char = chr($pad);
$source .= str_repeat($char, $pad);
}
return $source;
}
/**
* 解密
* @param $encrypted
* @param $key
* @param string $iv
* @return false|string
*/
public static function decrypt3DES($encrypted, $key, $iv = "12345678910111213")
{
$key = pack("H48", $key);
$iv = pack("H16", $iv);
$encrypted = base64_decode($encrypted);
$td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
mcrypt_generic_init($td, $key, $iv);
$decrypted = mdecrypt_generic($td, $encrypted);
mcrypt_generic_deinit($td);
mcrypt_module_close($td);
$decrypted = self::stripPKSC5Padding($decrypted);
return $decrypted;
}
/**
* @param $source
* @return false|string
*/
public static function stripPKSC5Padding($source)
{
$char = substr($source, -1, 1);
$num = ord($char);
if ($num > 8) {
return $source;
}
$len = strlen($source);
for ($i = $len - 1; $i >= $len - $num; $i--) {
if (ord(substr($source, $i, 1)) != $num) {
return $source;
}
}
$source = substr($source, 0, -$num);
return $source;
}
/**
* @param $str
* @return string
*/
public static function removeBR($str)
{
$len = strlen($str);
$newstr = "";
$str = str_split($str);
for ($i = 0; $i < $len; $i++) {
if ($str[$i] != '\n' and $str[$i] != '\r') {
$newstr .= $str[$i];
}
}
return $newstr;
}
}
使用方法
echo TripleEncrypt::decrypt3DES("Bth5XXdhUQIQLYXOcAreTQ==","************************************************");
输出:
184********
注意:
- 这里的key是48位的,云闪付提供的对称秘钥(symmetricKey)
- php版本高于7.1.0需要安装mcrypt扩展 http://pecl.php.net/package/mcrypt