欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

常用对称加密算法 有大用

shiping1 的头像

常用对称加密算法(DES/AES)类(PHP)

分类: PHP 3800人阅读 评论(7) 收藏 举报

看注释,啥也不说了,欢迎各种跨平台测试!

  1. /** 
  2.  * 常用对称加密算法类 
  3.  * 支持密钥:64/128/256 bit(字节长度8/16/32) 
  4.  * 支持算法:DES/AES(根据密钥长度自动匹配使用:DES:64bit AES:128/256bit) 
  5.  * 支持模式:CBC/ECB/OFB/CFB 
  6.  * 密文编码:base64字符串/十六进制字符串/二进制字符串流 
  7.  * 填充方式: PKCS5Padding(DES) 
  8.  * 
  9.  * @author: linvo 
  10.  * @version: 1.0.0 
  11.  * @date: 2013/1/10 
  12.  */  
  13. class Xcrypt{  
  14.   
  15.     private $mcrypt;  
  16.     private $key;  
  17.     private $mode;  
  18.     private $iv;  
  19.     private $blocksize;  
  20.   
  21.     /** 
  22.      * 构造函数 
  23.      * 
  24.      * @param string 密钥 
  25.      * @param string 模式 
  26.      * @param string 向量("off":不使用 / "auto":自动 / 其他:指定值,长度同密钥) 
  27.      */  
  28.     public function __construct($key$mode = 'cbc'$iv = "off"){  
  29.         switch (strlen($key)){  
  30.         case 8:  
  31.             $this->mcrypt = MCRYPT_DES;  
  32.             break;  
  33.         case 16:  
  34.             $this->mcrypt = MCRYPT_RIJNDAEL_128;  
  35.             break;  
  36.         case 32:  
  37.             $this->mcrypt = MCRYPT_RIJNDAEL_256;  
  38.             break;  
  39.         default:  
  40.             die("Key size must be 8/16/32");  
  41.         }  
  42.   
  43.         $this->key = $key;  
  44.   
  45.         switch (strtolower($mode)){  
  46.         case 'ofb':  
  47.             $this->mode = MCRYPT_MODE_OFB;  
  48.             if ($iv == 'off'die('OFB must give a IV'); //OFB必须有向量  
  49.             break;  
  50.         case 'cfb':  
  51.             $this->mode = MCRYPT_MODE_CFB;  
  52.             if ($iv == 'off'die('CFB must give a IV'); //CFB必须有向量  
  53.             break;  
  54.         case 'ecb':  
  55.             $this->mode = MCRYPT_MODE_ECB;  
  56.             $iv = 'off'//ECB不需要向量  
  57.             break;  
  58.         case 'cbc':  
  59.         default:  
  60.             $this->mode = MCRYPT_MODE_CBC;  
  61.         }  
  62.   
  63.         switch (strtolower($iv)){  
  64.         case "off":  
  65.             $this->iv = null;  
  66.             break;  
  67.         case "auto":  
  68.             $source = PHP_OS=='WINNT' ? MCRYPT_RAND : MCRYPT_DEV_RANDOM;  
  69.             $this->iv = mcrypt_create_iv(mcrypt_get_block_size($this->mcrypt, $this->mode), $source);  
  70.             break;  
  71.         default:  
  72.             $this->iv = $iv;  
  73.         }  
  74.   
  75.      
  76.     }  
  77.   
  78.   
  79.     /** 
  80.      * 获取向量值 
  81.      * @param string 向量值编码(base64/hex/bin) 
  82.      * @return string 向量值 
  83.      */  
  84.     public function getIV($code = 'base64'){  
  85.         switch ($code){  
  86.         case 'base64':  
  87.             $ret = base64_encode($this->iv);  
  88.             break;  
  89.         case 'hex':  
  90.             $ret = bin2hex($this->iv);  
  91.             break;  
  92.         case 'bin':  
  93.         default:  
  94.             $ret = $this->iv;  
  95.         }  
  96.         return $ret;  
  97.     }  
  98.   
  99.   
  100.     /** 
  101.      * 加密 
  102.      * @param string 明文 
  103.      * @param string 密文编码(base64/hex/bin) 
  104.      * @return string 密文 
  105.      */  
  106.     public function encrypt($str$code = 'base64'){  
  107.         if ($this->mcrypt == MCRYPT_DES) $str = $this->_pkcs5Pad($str);  
  108.   
  109.         if (isset($this->iv)) {  
  110.             $result = mcrypt_encrypt($this->mcrypt, $this->key, $str$this->mode, $this->iv);    
  111.         } else {  
  112.             @$result = mcrypt_encrypt($this->mcrypt, $this->key, $str$this->mode);    
  113.         }  
  114.   
  115.         switch ($code){  
  116.         case 'base64':  
  117.             $ret = base64_encode($result);  
  118.             break;  
  119.         case 'hex':  
  120.             $ret = bin2hex($result);  
  121.             break;  
  122.         case 'bin':  
  123.         default:  
  124.             $ret = $result;  
  125.         }  
  126.    
  127.         return $ret;  
  128.    
  129.     }  
  130.   
  131.     /** 
  132.      * 解密  
  133.      * @param string 密文 
  134.      * @param string 密文编码(base64/hex/bin) 
  135.      * @return string 明文 
  136.      */  
  137.     public function decrypt($str$code = "base64"){      
  138.         $ret = false;  
  139.   
  140.         switch ($code){  
  141.         case 'base64':  
  142.             $str = base64_decode($str);  
  143.             break;  
  144.         case 'hex':  
  145.             $str = $this->_hex2bin($str);  
  146.             break;  
  147.         case 'bin':  
  148.         default:  
  149.         }  
  150.   
  151.         if ($str !== false){  
  152.             if (isset($this->iv)) {  
  153.                 $ret = mcrypt_decrypt($this->mcrypt, $this->key, $str$this->mode, $this->iv);    
  154.             } else {  
  155.                 @$ret = mcrypt_decrypt($this->mcrypt, $this->key, $str$this->mode);    
  156.             }  
  157.             if ($this->mcrypt == MCRYPT_DES) $ret = $this->_pkcs5Unpad($ret);  
  158.             $ret = trim($ret);  
  159.         }  
  160.   
  161.         return $ret;   
  162.     }   
  163.   
  164.   
  165.   
  166.     private function _pkcs5Pad($text){  
  167.         $this->blocksize = mcrypt_get_block_size($this->mcrypt, $this->mode);    
  168.         $pad = $this->blocksize - (strlen($text) % $this->blocksize);  
  169.         return $text . str_repeat(chr($pad), $pad);  
  170.     }  
  171.   
  172.     private function _pkcs5Unpad($text){  
  173.         $pad = ord($text{strlen($text) - 1});  
  174.         if ($pad > strlen($text)) return false;  
  175.         if (strspn($textchr($pad), strlen($text) - $pad) != $padreturn false;  
  176.         $ret = substr($text, 0, -1 * $pad);  
  177.         return $ret;  
  178.     }  
  179.   
  180.     private function _hex2bin($hex = false){  
  181.         $ret = $hex !== false && preg_match('/^[0-9a-fA-F]+$/i'$hex) ? pack("H*"$hex) : false;      
  182.         return $ret;  
  183.     }  
  184.   
  185.   
  186.   
  187. }  

给个小demo吧
  1. <?php  
  2. header('Content-Type:text/html;Charset=utf-8;');  
  3.   
  4. include "xcrypt.php";  
  5.   
  6. echo '<pre>';  
  7. //////////////////////////////////////  
  8. $a = isset($_GET['a']) ? $_GET['a'] : '测试123';  
  9.   
  10. //密钥  
  11. $key = '12345678123456781234567812345678'//256 bit  
  12. $key = '1234567812345678'//128 bit  
  13. $key = '12345678'//64 bit  
  14.   
  15. //设置模式和IV   //第三个参数为向量,最好不要用'auto',因为auto每次都
  16. //变化, 在其它的php中不能逆向取值 ,我们 给它一个固定值 (位数与密钥相同)
  17. $m = new Xcrypt($key'cbc''auto');  
  18.   
  19. //获取向量值  
  20. echo '向量:';  
  21. var_dump($m->getIV());  
  22.   
  23. //加密  
  24. $b = $m->encrypt($a'base64');  
  25. //解密  
  26. $c = $m->decrypt($b'base64');  
  27.   
  28. echo '加密后:';  
  29. var_dump($b);  
  30. echo '解密后:';  
  31. var_dump($c);  
  32.   
  33.   
  34. /////////////////////////////////////////  
  35. echo '</pre>'
来自 http://blog.csdn.net/linvo/article/details/8497056




对于大部分密码加密,我们可以采用md5、sha1等方法。可以有效防止数据泄露,但是这些方法仅适用于无需还原的数据加密。

对于需要还原的信息,则需要采用可逆的加密解密算法。

下面一组PHP函数是实现此加密解密的方法:

加密算法如下:

function encrypt($data, $key)
{
	$key	=	md5($key);
    $x		=	0;
    $len	=	strlen($data);
    $l		=	strlen($key);
    for ($i = 0; $i < $len; $i++)
    {
        if ($x == $l) 
        {
        	$x = 0;
        }
        $char .= $key{$x};
        $x++;
    }
    for ($i = 0; $i < $len; $i++)
    {
        $str .= chr(ord($data{$i}) + (ord($char{$i})) % 256);
    }
    return base64_encode($str);
}

解密算法如下:

function decrypt($data, $key)
{
	$key = md5($key);
    $x = 0;
    $data = base64_decode($data);
    $len = strlen($data);
    $l = strlen($key);
    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 $str;
}

上述加密解密的过程均需要用到一个加密密钥(即参数$key)。

 

$data = 'PHP加密解密算法';		// 被加密信息
$key = '123';					// 密钥
$encrypt = encrypt($data, $key);
$decrypt = decrypt($encrypt, $key);
echo $encrypt, "\n", $decrypt;

上述将输出类似如下结果:

gniCSOzZG+HnS9zcFea7SefNGhXF
PHP加密解密算法

从上述结果可以看出,这是一组可逆的加密解密算法,可以用于部分需要还原的数据加密。

来自 http://www.phper.org.cn/index.php?m=content&a=show&post_id=387



普通分类: