首页 > 代码库 > PHP 3DES 算法,与Java中的DESede兼容

PHP 3DES 算法,与Java中的DESede兼容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
 
class Crypt3Des {
    public $key = "000000000000000000000000";
    public $iv = ‘00000000‘;
 
    //加密
    public function encrypt($input) {
        $input = $this->addPKCS7Padding($input);
        $td = mcrypt_module_open(MCRYPT_3DES, ‘‘, MCRYPT_MODE_ECB, ‘‘);
        mcrypt_generic_init($td, $this->key, $this->iv);
        $data = mcrypt_generic($td, $input);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        $data = $this->removeBR(base64_encode($data));
        return $data;
    }
 
    //解密
    public function decrypt($encrypted) {
        $encrypted = base64_decode($encrypted);
        $td = mcrypt_module_open(MCRYPT_3DES, ‘‘, MCRYPT_MODE_ECB, ‘‘);
        mcrypt_generic_init($td, $this->key, $this->iv);
        $decrypted = mdecrypt_generic($td, $encrypted);
        mcrypt_generic_deinit($td);
        mcrypt_module_close($td);
        $decrypted = $this->stripPKSC5Padding($decrypted);
        return $decrypted;
    }
 
    //填充至8的倍数
    private 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;
    }
 
    // 去除加密前的填充
    public 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;
    }
 
    //删除回车和换行
    public 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;
    }
}

解释:

在Java中如果没有明确指定3DES算法的加密模式和填充方式,则默认为 DESede/ECB/PKCS5Padding 。

ECB模式不需要初始化向量,所以以上代码中的iv实际是没有用到的。

在C#中,不支持PKCS5Padding填充方式,但支持PKCS7Padding填充方式。这两种填充方式的区别是,PKCS5Padding明确规定加密块大小为8个字节,而PKCS7Padding并没有明确规定加密块的大小,只要在1-255之间就OK。但C#中默认的加密块大小为8个字节,所以如果不改变C#的默认值,PKCS5Padding与PKCS7Padding也是兼容的。



来自为知笔记(Wiz)