美文网首页
PHP封装三种加解密方法!

PHP封装三种加解密方法!

作者: DragonersLi | 来源:发表于2017-08-11 22:19 被阅读30次
 
/*
* PHP封装加密解密类 
*/
class secret{
    
    //定义秘钥 key
    private $key = "Dragoners.Li";
    
    
    //动态加密 
    public function php_encrypt($txt) { 
       srand((double)microtime() * 1000000);
       $enkey = md5(rand(0,32000));
       $ctr = 0;
       $tmp = '';
       for($i = 0;$i<strlen($txt);$i++) {
        $ctr = $ctr == strlen($enkey) ? 0 : $ctr;
        $tmp .= $enkey[$ctr].($txt[$i]^$enkey[$ctr++]);
       }
       return base64_encode(self::__key($tmp,$this -> key));
    }

    //解密
    public function php_decrypt($txt) { 
       $txt = self::__key(base64_decode($txt),$this -> key);
       $tmp = '';
       for($i = 0;$i < strlen($txt); $i++) {
        $md5 = $txt[$i];
        $tmp .= $txt[++$i] ^ $md5;
       }
       return $tmp;
    }
   
    private function __key($txt,$enkey) {
       $enkey = md5($enkey);
       $ctr = 0;
       $tmp = '';
       for($i = 0; $i < strlen($txt); $i++) {
        $ctr = $ctr == strlen($enkey) ? 0 : $ctr;
        $tmp .= $txt[$i] ^ $enkey[$ctr++];
       }
       return $tmp;
    }
 
    
    
    
    //动态加密解密函数,实时变化.适合app接口调用key!
    function authcode($string, $operation = 'DECODE', $expiry = 0, $key = '') { 

            $ckey_length = 4; // 动态密匙长度,相同的明文会生成不同密文就是依靠动态密匙 
            $key = md5($key ? $key : $this -> key); // 密匙 

            $keya = md5(substr($key, 0, 16)); // 密匙a会参与加解密 

            $keyb = md5(substr($key, 16, 16)); // 密匙b会用来做数据完整性验证 

            $keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): // 密匙c用于变化生成的密文 
            substr(md5(microtime()), -$ckey_length)) : ''; 

            $cryptkey = $keya.md5($keya.$keyc); // 参与运算的密匙 
            $key_length = strlen($cryptkey); 
            // 明文,前10位用来保存时间戳,解密时验证数据有效性,10到26位用来保存$keyb(密匙b), 
            //解密时会通过这个密匙验证数据完整性 
            // 如果是解码的话,会从第$ckey_length位开始,因为密文前$ckey_length位保存 动态密匙,以保证解密正确 
            $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : 
            sprintf('%010d', $expiry ? $expiry + 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])); // 从密匙簿得出密匙进行异或,再转成字符 
        } 
        if($operation == 'DECODE') { 
            // 验证数据有效性,请看未加密明文的格式 
            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 ''; 
            } 
        }else{ 
            // 把动态密匙保存在密文里,这也是为什么同样的明文,生产不同密文后能解密的原因 
            // 因为加密后的密文可能是一些特殊字符,复制过程可能会丢失,所以用base64编码 
            return $keyc.str_replace('=', '', base64_encode($result)); 
        } 
    }  
 

 
    /*
    * 非动态加密解密函数 
    * @param $string 要加密或解密的字符串
    * @param $operation 值为true解密 (0:加密;1:解密)
    *
    */
    public function encrypt($string,$operation = 0){ 
            $key = md5($this->key); 
            $key_length = strlen($key); 
            $string = $operation ? base64_decode($string):substr(md5($string.$key),0,8).$string; 
            $string_length = strlen($string); 
            $rndkey = $box=array(); 
            $result = ''; 
            for($i=0;$i<= 255;$i++){ 
                $rndkey[$i]=ord($key[$i%$key_length]); 
                $box[$i]=$i; 
            } 
            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])); 
            } 
            if($operation){ 
                if(substr($result,0,8)==substr(md5(substr($result,8).$key),0,8)){ 
                    return substr($result,8); 
                }else{ 
                    return''; 
                }  
            }else{ 
                return str_replace('=','',base64_encode($result)); 
            } 
    }
  
}



该类封装了三个加解密函数,调用示例如下:

#动态加解密一:
 $secret = new secret;//实例化对象
 $text = "我还好,那你呢?";//加密文本
 $str_encrypt = $secret->php_encrypt($text);
 print_R($str_encrypt); //加密
 print('<br>');
 $str_decrypt = $secret->php_decrypt('UuYCjAbEBr4C7FXBVrEOqwC5V7QM61GJXecGhAD5ArQH6AOlALYBwFCjB+QFu1vE');
 print($str_decrypt);//解密   
Paste_Image.png
#动态加解密二:
 $secret = new secret;//实例化对象
 $text = "我还好,那你呢?";//加密文本  
  
echo $str_encode = $secret->authcode($text,'ENCODE',$expiry = 0, $key = ''); //加密   
echo"<br>";
echo $secret->authcode($str_encode,'DECODE',$expiry = 0, $key = ''); //解密

#$expiry 和 $key 可以不传 ,使用默认值
echo $str_encode = $secret->authcode($text,'ENCODE'); //加密   
echo"<br>";
echo $secret->authcode($str_encode,'DECODE'); //解密
Paste_Image.png
#非动态加解密:

 $secret = new secret;//实例化对象
 $text = "我还好,那你呢?";//加密文本 
echo  $str_encrypt = $secret->encrypt($text); //加密 
echo"<br>";
echo $secret->encrypt($str_encrypt, true);//解密 
  
Paste_Image.png

动态加密解密函数


//加密
  function encrypt($data, $key = '', $expire = 0) {
    $key  = md5($key);
    $data = base64_encode($data);
    $x    = 0;
    $len  = strlen($data);
    $l    = strlen($key);
    $char = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time():0);

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256);
    }
    return str_replace(array('+','/','='),array('-','_',''),base64_encode($str));
}

//解密
  function decrypt($data, $key = ''){
    $key    = md5($key);
    $data   = str_replace(array('-','_'),array('+','/'),$data);
    $mod4   = strlen($data) % 4;
    if ($mod4) {
       $data .= substr('====', $mod4);
    }
    $data   = base64_decode($data);
    $expire = substr($data,0,10);
    $data   = substr($data,10);

    if($expire > 0 && $expire < time()) {
        return '';
    }
    $x      = 0;
    $len    = strlen($data);
    $l      = strlen($key);
    $char   = $str = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    for ($i = 0; $i < $len; $i++) {
        if (ord(substr($data, $i, 1))<ord(substr($char, $i, 1))) {
            $str .= chr((ord(substr($data, $i, 1)) + 256) - ord(substr($char, $i, 1)));
        }else{
            $str .= chr(ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)));
        }
    }
    return base64_decode($str);
}

调用示例:

echo encrypt("hello",'DragonersLi', 10); //加密
echo decrypt("MDAwMDAwMDAwMJd9u9WTfply","DragonersLi");//解密 

相关文章

网友评论

      本文标题:PHP封装三种加解密方法!

      本文链接:https://www.haomeiwen.com/subject/dpsrrxtx.html