PS:原创文章,如需转载,请注明出处,谢谢!
本文地址: http://flyer0126.iteye.com/blog/ 1753735
PHP的加密函数crypt(), 这一函数完成被称作单向加密的功能,它可以加密一些明码,但不能够将密码转换为原来的明码,这种方式相对来讲比较安全。
<?php // 可用散列允许的最长可用盐值 print "My system salt size is: ". CRYPT_SALT_LENGTH."<br/>"; // 测试串 $str = "flyer0126"; // 执行加密 $salt = substr($str, 0, 2); $pass = crypt($str, $salt); // 将$pass存入数据库,下次使用时可使用相同算法进行验证 ...... echo $pass; // flmnB14trocYs
注:$salt 作为可选的盐值字符串。如果没有提供,算法行为将由不同的算法实现决定,并可能导致不可预料的结果。
相比之下,PHP的扩展Mcrypt功能就强大很多了,它是一个功能强大的加密扩展库。Mcrypt的优点不仅仅在于其提供的加密算法较多,还在于它可以对数据进行加/解密处理。
1. 安装
windows下默认已经打包好所需要的库,这点可以在phpinfo() 中验证是否存在mcrypt 模块。
Linux版的PHP自身不打包该库,需要自行到官方网站下载代码进行编译安装。
2. 介绍
参数:
1). cipher
One of the MCRYPT_ciphername constants, or the name of the algorithm as string.
2). key
The key with which the data will be encrypted. If it's smaller than the required keysize, it is padded with '\0'. It is better not to use ASCII strings for keys. It is recommended to use the mhash functions to create a key from a string.
3). data
The data that will be encrypted with the given cipher and mode. If the size of the data is not n * blocksize, the data will be padded with '\0'. The returned crypttext can be larger than the size of the data that was given by data.
4). mode
One of the MCRYPT_MODE_modename constants, or one of the following strings: "ecb", "cbc", "cfb", "ofb", "nofb" or "stream".
5). iv
Used for the initialization in CBC, CFB, OFB modes, and in some algorithms in STREAM mode. If you do not supply an IV, while it is needed for an algorithm, the function issues a warning and uses an IV with all its bytes set to '\0'.
Mcrypt支持四种块加密模型:
1).MCRYPT_MODE_ECB (electronic codebook) 适合对小数量随机数据的加密,比如加密用户的登录密码之类的。
2).MCRYPT_MODE_CBC (cipher block chaining) 适合加密安全等级较高的重要文件类型。
3). MCRYPT_MODE_CFB ( cipher feedback ) 适合于需要对数据流的每一个字节进行加密的场合。
4).MCRYPT_MODE_OFB (output feedback, in 8bit) 和CFB模式兼容,但比CFB模式更安全。CFB模式会引起加密的错误扩散,如果一个byte出错,则其后续的所有byte都会出错。OFB模式则不会有 此问题。但该模式的安全度不是很高,不建议使用。
5). MCRYPT_MODE_NOFB (output feedback, in nbit) 和OFB兼容,由于采用了块操作算法,安全度更高。
6). MCRYPT_MODE_STREAM 是为了WAKE或者RC4等流加密算法提供的额外模型。 NOFB和STREAM仅当mycrypt的版本号大于等于 libmcrypt-2.4.x才有效。
3. 应用
<?php /** * 扩展Mcrypt应用类--加密解密 * @author flyer0126 * @since 2012/12 */ class Mcrypt { // 加密密钥 private $key = ''; // 加密算法 private $cipher = ''; // 加密模式 private $mode = ''; /** * 构造器 * @param [type] $cipher [description] */ function __construct($cipher) { if (!function_exists('mcrypt_module_open')) { return false; } if (empty($cipher)) { return false; } $this->cipher = $cipher; } /** * 设置mode * @param [type] $mode [description] */ function setMode($mode) { if (!strlen($mode)) { return false; } if (!in_array($mode, mcrypt_list_modes())) { return false; } $this->mode = $mode; } /** * 设置mode * @param [type] $key [description] * @return [type] [description] */ function setkey($key) { if (empty($key)) { return false; } $vi_size = $this->get_iv_size(); $key = hash('md5', $key); $this->key = strlen($key)>$vi_size ? substr($key, 0, $vi_size) : $key; } /** * 获取vi_size * @return [type] [description] */ function get_iv_size() { if (empty($this->cipher) || empty($this->mode)) { return false; } return mcrypt_get_iv_size($this->cipher, $this->mode); } /** * 获取iv * @return [type] [description] */ function get_iv() { $vi_size = $this->get_iv_size(); return mcrypt_create_iv($vi_size); } /** * 加密 * @param [type] $data [description] * @return [type] [description] */ function encrypt($data=null) { if (null == $data || empty($this->key)) { var_dump($this);return false; } // CFB和OFB是必须有IV, CBC和EBC则是可选的 $vi = $this->get_iv(); if (in_array($this->mode, array(MCRYPT_MODE_OFB, MCRYPT_MODE_CFB)) && empty($vi)) { exit("Error: vi is empty."); } return mcrypt_encrypt($this->cipher, $this->key, $data, $this->mode, $vi); } /** * 解密 * @param [type] $data [description] * @return [type] [description] */ function decrypt($data = null) { if (null == $data) { return false; } $vi = $this->get_iv(); return mcrypt_decrypt($this->cipher, $this->key, $data, $this->mode, $vi); } }
测试应用如下:
<?php // 测试内容 $data = "这是一段测试内容,by flyer0126 at 2012/12/25"; // 密钥 $key = "key:111"; // 密码类型 $cipher = MCRYPT_DES; // 密码模式 $mode = MCRYPT_MODE_ECB; // 测试Mcrypt的加密解密功能 $mc = new Mcrypt($cipher); $mc->setMode($mode); $mc->setkey($key); $ret = $mc->encrypt($data); $dret = $mc->decrypt($ret); // 输出 echo '$ret:'.$ret."<br/>".'$dret:'.$dret;exit; /** 输出内容(utf-8编码) **/ $ret:�c�qK:~�E']�!%@��#�(���`��0�=�J��1� �o�h0�Yv� $dret:这是一段测试内容,by flyer0126 at 2012/12/25
可能会出现的几个常见问题:
1). Warning: mcrypt_encrypt() [function.mcrypt-encrypt]: Attempt to use an empty IV, which is NOT recommend in ...
原因:需要iv的加密模式加密时没有提供有效的iv,此类模式包括:CBC, CFB, OFB。
2). Warning: mcrypt_encrypt() [function.mcrypt-encrypt() Size of key is too large for this algorithm
原因:key值处理问题,key值经md5加密后,增强安全性,需要根据vi_size的值进行截取,否则输出长度警告。