PHP 实现 3Des ECB 加密算法

这两天对接第三方,对方有个 token 使用的是 3Des ECB 加密算法,并且非常贴心的提供了一段 Java 实现的 demo,具体如下:

Java 版本

public static String Des3EncodeECB(String originData, String SECRET) throws Exception {
    DESedeKeySpec dks = new DESedeKeySpec(SECRET.getBytes("UTF-8"));
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
    SecretKey securekey = keyFactory.generateSecret(dks);
    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, securekey);
    byte[] b = cipher.doFinal(originData.getBytes("UTF-8"));
    return new String(Base64.encodeBase64(b), "UTF-8").replaceAll("\r", "").replaceAll("\n", "");
}
 
public static void main(String[] args) throws Exception {
    System.out.println(Des3EncodeECB("1234", "RV3n1wsaREGRm4G1F5AFZpEG")); // 结果:82YoIgPcgTs=
}

殊不知我们使用的是世界上最好的语言。询问对方有无 PHP 版本时,告知没有。

那就只能自己实现了(当然是搜索引擎)。

最后花了小半天,解决了问题,将结果记录如下。

PHP5 版本

class TripleDesEcb{
 
    /**加密
     * @param $text string 文本内容
     * @param $key string 秘钥 max 24
     * @return string
     */
    public function encrypt($text,$key)
    {
 
        $iv   = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_TRIPLEDES,MCRYPT_MODE_ECB), MCRYPT_RAND);
        $text = $this->pkcs5Pad($text);
        $td = mcrypt_module_open(MCRYPT_3DES,'',MCRYPT_MODE_ECB,'');
        mcrypt_generic_init($td,$key,$iv);
        $data = base64_encode(mcrypt_generic($td, $text));
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        print_r($data);
        return $data;
 
    }
 
    /**解密
     * @param $text
     * @param $key
     */
    public function decrypt($text,$key)
    {
        $iv   = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_TRIPLEDES,MCRYPT_MODE_ECB), MCRYPT_RAND);
        $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_ECB, '');
        mcrypt_generic_init($td, $key, $iv);
        $data  = $this->pkcs5UnPad(mdecrypt_generic($td, base64_decode($text)));
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        print_r($data);
    }
 
    /**
     * @param $text
     * @return string
     */
    private function pkcs5Pad($text)
    {
        $pad = 8 - (strlen($text) % 8);
        return $text . str_repeat(chr($pad), $pad);
    }
 
    /**
     * @param $text
     * @return bool|string
     */
    private function pkcs5UnPad($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);
    }
}
 
$a = new TripleDesEcb();
$key = 'RV3n1wsaREGRm4G1F5AFZpEG';
$r = $a->encrypt('1234',$key); // 结果:82YoIgPcgTs=
echo "----";
$a->decrypt($r,$key);

目前线上环境跑的是 5.6 的 PHP,但是有计划升级到 7.X 版本,而 mcrypt_ 系列函数在 7.1 版本废弃掉了,我们自然是不能使用该版了。

PHP7 版本(兼容 PHP5.3+)

class TripleDES{
    public static function encrypt($str,$key){
        $str = self::pkcs5_pad($str, 8);
        if (strlen($str) % 8) {
            $str = str_pad($str, strlen($str) + 8 - strlen($str) % 8, "\0");
        }
        $sign = openssl_encrypt($str, 'DES-EDE3', $key, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, '');
        return base64_encode($sign);
    }
 
    private static function pkcs5_pad($text, $blocksize) {
        $pad = $blocksize - (strlen($text) % $blocksize);
        return $text . str_repeat(chr($pad), $pad);
    }
 
}
 
echo TripleDES::encrypt('34234324', 'RV3n1wsaREGRm4G1F5AFZpEG'); // 结果:82YoIgPcgTs=

Java 版本、PHP5 版本、PHP7 版本最终结果一致。

参考文档

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页