php authcode动态加密解密类实现代码

发布时间:2021-01-17编辑:脚本学堂
一个php实现的动态加密与解密类,php authcode动态加密解密类的实例代码,有需要的朋友参考下。

用php实现的authcode加密与解密类,与discuz中的authcode加密解密类不同,php中用于动态加密解密的类,动态密匙可使每次加密密文都不一样,可设置密文有效期,封装成类方便调用。

完整代码:

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
//示例
$wl = new authcode();
$ens = $wl->encrypt("hello jb200.com");
$des = $wl->decrypt($ens);
echo "加密前:hello jb200.com<br/>加密后:$ens <br/>解密后:$des<br/>";
 
//以下为类的源码
class authcode{
    public $key="http://www.jb200.com";
    public $exptime=0;
       
    public function __construct($key="",$exptime=0){
        $this->key =$key;
        $this->exptime=$exptime;
    }
    private function dechex2($int){ //十进制转为二位16进制
        if ($int< 0 or $int >255 ){
            return "NN";
        }else{
            $ref = dechex($int);
            $ref = strlen($ref)<>2 ? "0".$ref : $ref;
            return $ref;
        }
    
    public function encrypt($string, $key="", $exptime = 0) {
        /* ====     加密函数   ====*/
        // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
        $ckey_length = 4;
        //密文有效期
        $exptime = $exptime ? $exptime : $this->exptime;
        // 密匙
        $key = md5($key ? $key : $this->key);
        // 密匙a会参与加解密
        $keya = md5(substr($key, 0, 16));
        // 密匙b会用来做数据完整性验证
        $keyb = md5(substr($key, 16, 16));
        // 密匙c用于变化生成的密文
        $keyc =$ckey_length ? substr(md5(microtime()), -$ckey_length) : '';
           
        // 参与运算的密匙
        $cryptkey = $keya.md5($keya.$keyc);
        $key_length = strlen($cryptkey);
        // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),解密时会通过这个密匙验证数据完整性
        // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确
        $string = sprintf('%010d', $exptime ? $exptime + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
        $string_length = strlen($string);
        $result = '';
        $box = range(0, 255);
        $rndkey = array();
        // 产生密匙簿
        for($i = 0; $i <= 255; $i++) {
            $rndkey[$i] = ord($cryptkey[$i % $key_length]);
        }
        // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
        for($j = $i = 0; $i < 256; $i++) {
            $j = ($j + $box[$i] + $rndkey[$i]) % 256;
            $tmp = $box[$i];
            $box[$i] = $box[$j];
            $box[$j] = $tmp;
        }
           
        // 核心加解密部分
        for($a = $j = $i = 0; $i < $string_length; $i++) {
            $a = ($a + 1) % 256;
            $j = ($j + $box[$a]) % 256;
            $tmp = $box[$a];
            $box[$a] = $box[$j];
            $box[$j] = $tmp;
        // 从密匙簿得出密匙进行异或,再转成字符
            $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
           
        }
            return $keyc.base64_encode($result);
               
    } // end encrypt function
    public function decrypt($string, $key="", $exptime = 0) {
            /*===  解密函数  ===*/
            // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙
            $ckey_length = 4;
            //密文有效期
            $exptime = $exptime ? $exptime : $this->exptime;
            // 密匙
            $key = md5($key ? $key : $this->key);
            // 密匙a会参与加解密
            $keya = md5(substr($key, 0, 16));
            // 密匙b会用来做数据完整性验证
            $keyb = md5(substr($key, 16, 16));
            // 密匙c用于变化生成的密文
            $keyc = $ckey_length ? substr($string, 0, $ckey_length) : '';
            // 参与运算的密匙 (www.jb200.com <a href="http://www.jb200.com/jb/" target="_blank" class="infotextkey">脚本</a>学堂)
            $cryptkey = $keya.md5($keya.$keyc);
            $key_length = strlen($cryptkey);
            // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b),解密时会通过这个密匙验证数据完整性
            // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确
            $string = base64_decode(substr($string, $ckey_length)) ;
            //echo "解码后:16进制:$string <br/>";
            $string_length = strlen($string);
               
            $result = '';
            $box = range(0, 255);
            $rndkey = array();
            // 产生密匙簿
            for($i = 0; $i <= 255; $i++) {
                $rndkey[$i] = ord($cryptkey[$i % $key_length]);
            }
            // 用固定的算法,打乱密匙簿,增加随机性,好像很复杂,实际上对并不会增加密文的强度
            for($j = $i = 0; $i < 256; $i++) {
                $j = ($j + $box[$i] + $rndkey[$i]) % 256;
                $tmp = $box[$i];
                $box[$i] = $box[$j];
                $box[$j] = $tmp;
            } // by www.jb200.com
               
            // 核心加解密部分
            for($a = $j = $i = 0; $i < $string_length ; $i++) {
                $a = ($a + 1) % 256;
                $j = ($j + $box[$a]) % 256;
                $tmp = $box[$a];
                $box[$a] = $box[$j];
                $box[$j] = $tmp;
                   
                // 从密匙簿得出密匙进行异或,再转成字符
   
                $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
            }
   
                // substr($result, 0, 10) == 0 验证数据有效性
                // substr($result, 0, 10) - time() > 0 验证数据有效性
                // substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16) 验证数据完整性
                // 验证数据有效性,请看未加密明文的格式
                if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) ==
substr(md5(substr($result, 26).$keyb), 0, 16)) {
                    return substr($result, 26);
                } else {
                    return '';
                }
        
        //end function decrypt         
}//end class
?>
28