在开发中,很多时候我们在前后端交互中需要对一些敏感数据进行一定的加密。PHP中有提供了mcrypt的这样一个加密扩展实现对数据的加密解密。
1.Mcrypt扩展库
官网:http://php.net/manual/zh/book.mcrypt.php
在低版本的PHP中需要在配置文件php.ini中显式添加对扩展的引用,同时要保证扩展引用目录中有相应的扩展文件;在高版本的PHP中,Windows下似乎默认开启了mcrypt的扩展,既不需要在配置文件php.ini中做配置,在扩展引用目录中也没有看到相应的扩展文件,在linux下则需要安装对应的mcrypt.so扩展。
1)Mcrypt库的安装
Linux下安装Mcrypt
安装步骤如下:
1.查看当前php 版本 #php -version
2.如果当前linux 中有php的源码包最好,如果没有源码包,需要去下载一个原码包,上传到服务器解压
3.确认是否已安装libmcrypt
ldconfig -p | grep libmcrypt
如果没有安装:
下载地址:http://sourceforge.net/projects/mcrypt
可以同时下载libmcrypt 和 mcrypt
先安装libmcrypt, 默认安装目录为 /usr/local , PHP 手册建议--disable-posix-threads ,不知何故
./configure && make && make install
ldconfig
再安装mcrypt, 默认安装目录为 /usr/local
./configure --with-libmcrypt-prefix=/usr/local
4. 确认是否已安装mhash
ldconfig -p | grep mhash
如果没有安装:
下载地址:http://mhash.sourceforge.net/
./configure && make && make install
ldconfig
5.进入源码目录,安装mcrypt模块,这一步会生成一个mcrypt.so文件
cd php-x.x.x/ext/mcrypt
./configure --with-mcrypt=/usr/local/ && make && make install
6.在/etc/php.ini最后面加上一行:extension=/usr/lib/php/modules/mcrypt.so
7.重启php #service httpd restart
2)Mcrypt库常量
Mcrypt库支持20多种加密算法和8种加密模式,可以通过Mcrypt_list_algorithms()函数和mcrypt_list_modes()查看,代码如下:
<?php $en_dir = mcrypt_list_algorithms(); echo "Mcrypt支持的算法有:"; foreach($en_dir as $en_value){ echo $en_value." "; } ?>
<?php $mo_dir = mcrypt_list_modes(); echo "<p>Mcrypt支持的加密模式有:"; foreach($mo_dir as $mo_value){ echo $mo_value." "; } ?>
输出:
这些算法和模式在实际应用中要常用常量来表示,写到时候分别加上前缀MCRYPT_和MCRYPT_MODE_来表示,如:
TWOFISH的算法表示为:MCRYPT_TWOFISH
CBC的加密模式表示为:MCRYPT_MODE_CBC
Mcrypt支持四种块加密模型,简要说明如下:
a. MCRYPT_MODE_ECB(electronic codebook) 适合对小数量随机数据的加密,比如加密用户的登录密码之类的。
b. MCRYPT_MODE_CBC (cipher block chaining) 适合加密安全等级较高的重要文件类型。
c. MCRYPT_MODE_CFB (cipher feedback) 适合于需要对数据流的每一个字节进行加密的场合。
d. MCRYPT_MODE_OFB (output feedback, in 8bit) 和CFB模式兼容,但比CFB模式更安全。CFB模式会引起加密的错误扩散,如果一个byte出错,则其后续的所有byte都会出错。OFB模式则不会有此问题。但该模式的安全度不是很高,不建议使用。
e. MCRYPT_MODE_NOFB (output feedback, in nbit) 和OFB兼容,由于采用了块操作算法,安全度更高。
f. MCRYPT_MODE_STREAM 是为了WAKE或者RC4等流加密算法提供的额外模型。
NOFB和STREAM仅当mycrypt的版本号大于等于libmcrypt-2.4.x才有效。(现在基本上都是大于这个版本了,libmcrypt的最新主版本已经到4了)
查看支持的算法和模型
a. mcrypt_list_modes()列出当前环境支持的模型
b. mcrypt_list_algorithms()列出当前环境支持的算法
3)Mcrypt的应用
使用Mcrypt进行加密和解密不像使用md5()、sha1()等函数,直接调用即可。实例:
<?php echo"<br>"; $str = "被加密的内容:相见时难别亦难 东风无力百花残"; $key = "key:111"; $cipher = MCRYPT_DES; $modes = MCRYPT_MODE_ECB; //初始化向量 $iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher,$modes),MCRYPT_RAND); echo "加密前:".$str."<p>"; //加密: $str_encrypt = mcrypt_encrypt($cipher,$key,$str,$modes,$iv); echo "加密后:".$str_encrypt." <p>"; $str_decrypt = mcrypt_decrypt($cipher,$key,$str_encrypt,$modes,$iv); echo "还原:".$str_decrypt; ?>
输出:
加密前:被加密的内容:相见时难别亦难 东风无力百花残
加密后:€鞤"猀车摰 D瓇A�3Jo鷟�<咦N翢�-蟮E6�¬鄹[p}�"�
还原:被加密的内容:相见时难别亦难 东风无力百花残
对上述例中的函数几个实例讲解:
(1)string mcrypt_create_iv(int size, int source)
本函数用来建立向量初始化 (Initialization vector, IV) 的值。参数 size 为指定的向量初始化治募长度。参数 source 为随机资料的来源,来源可以是 MCRYPT_RAND (系统产生的随机值)、MCRYPT_DEV_RANDOM (UNIX 系统中 /dev/random 的资料)、MCRYPT_DEV_URANDOM (UNIX 系统中 /dev/urandom 的资料),若使用 MCRYPT_RAND 当做随机源,记得先使用 srand() 产生乱数种子。
$cipher = MCRYPT_TripleDES;
$block_size = mcrypt_get_block_size($cipher);
$iv = mcrypt_create_iv($block_size, MCRYPT_DEV_RANDOM);
(2)int mcrypt_get_iv_size ( string $cipher , string $mode )
获取由 cipher/mode 参数指定的初始向量大小。
mcrypt_enc_get_iv_size() 更加有用, 因为它使用由 mcrypt_module_open() 返回的资源作为参数。
cipher:MCRYPT_ciphername 常量中的一个,或者是字符串值的算法名称。
mode:MCRYPT_MODE_modename 常量中的一个,或以下字符串中的一个:"ecb","cbc","cfb","ofb","nofb" 和 "stream"。
返回值:返回初始向量的大小,以字节为单位。 如果发生错误,返回 FALSE。 如果指定的算法/模式不需要初始向量,返回 0。
(3)string mcrypt_encrypt ( string $cipher , string $key , string $data , string $mode [, string $iv ] )
初始化向量后,即可以使用Mcrypt_encrypt()函数对数据进行加密,该函数的5个参数分别如下:
cipher:加密算法。这里的加密算法可以和初始化向量中的加密算法不一样
key:秘钥
data:要加密的数据
mode:加密模式。可以和初始化向量中的模式不一样
iv:初始化向量。
(4)string mcrypt_decrypt ( string $cipher , string $key , string $data , string $mode [, string$iv ] )
解密函数mcrypt_decrypt()函数和加密函数mcrypt_encrypt ()参数几乎一样,唯一不同的是参数data,这里的data为需要解密的数据,而不是原始数据。
案例:
$key = "miyao";//密钥 $string="jiami"//需要加密的字符 //自带的加密函数 $crypttext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($key)))); $encrypted =trim($this->safe_b64encode($crypttext));//对特殊字符进行处理 $key="miyao" $crypttexttb=safe_b64decode($encrypted)//对特殊字符解析 $decryptedtb = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($crypttexttb), MCRYPT_MODE_CBC, md5(md5($key))), "\0")//解密函数 //处理特殊字符 publicfunction safe_b64encode($string) { $data = base64_encode($string); $data = str_replace(array('+','/','='),array('-','_',''),$data); return $data; } //解析特殊字符 public function safe_b64decode($string) { $data = str_replace(array('-','_'),array('+','/'),$string); $mod4 = strlen($data) % 4; if ($mod4) { $data .= substr('====', $mod4); } return base64_decode($data); }
5)mcrypt扩展的使用
加密
1、打开加密算法和模式
mcrypt_module_open('tripledes', '', ecb'', '');
第一个参数是使用的加密算法的名称,对应mcrypt_list_algorithms()输出的加密算法;第三个参数对应加密的模式,对应mcrypt_list_modes()输出的支持加密模式。
2、创建初始化向量
mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
PS.在Window平台下,第二个参数固定使用MCRYPT_RAND
3、初始化加密缓冲区
mcrypt_generic_init($td, $key, $iv);
$td为返回的加密描述符,$key为加密密钥,$iv为初始化向量
4、数据加密
$encrypted_data = mcrypt_generic($td, $data);
$td为加密描述符,$data为加密前的数据,数据加密函数返回加密后的字符串。
5、结束加密,执行清理工作
mcrypt_generic_deinit($td);
解密
1、打开解密算法和模式,同上,得到$td解密描述符
2、创建初始化向量,同上,得到$iv初始化向量
3、初始化解密缓冲区
mcrypt_generic_init($td,$key, $iv);
4、数据解密
$decrypted_data = mdecrypt_generic($td, $encrypted_data);
PS.$encrypted_data为解密前的密文,$decrypted_data为解密后的明文。
2.Mhash扩展库
官网:http://php.net/manual/zh/book.mhash.php
Mhash是基于离散数学原理的不可逆向的php加密方式扩展库,其在默认情况下不开启。mhash的可以用于创建校验数值,消息摘要,消息认证码,以及无需原文的关键信息保存(如密码)等。
1)安装,见上文已经过
2)Mhash库常量
Mhash库支持md5,sha,crc32等多种散列算法,可以使用mhash_count()和Mhash_get_hash_name()函数输出支持的算法名称,如下:
<?php $num = mhash_count();//函数返回最大的hash id echo "Mhash库支持的算法有:"; for($i = 0; $i <= $num; $i++){ echo $i."=>".mhash_get_hash_name($i)."";//输出每一个hash id 的名称 } ?>
输出:
注意:如果在实际应用中使用上面的常量,需要在算法名称前面加上 MHASH_作为前缀,比如 CRC32 表示为 MHASH_CRC32。
3)Mhash应用
相比Mcrypt扩展库30多个函数,Mhash只有5个函数,除了上面的介绍的两个外,还有3个函数。
int mhash_get_block_size ( int $hash )
该函数用来获取参数hash的区块大小,如int mhash_get_block_size (MHASH_CRC32)
string mhash ( int $hash , string $data [, string $key ] )
该函数返回一个哈希值,参数hash为要使用的算法;参数data是要加密的数据;参数key是加密使用的秘钥
string mhash_keygen_s2k ( int $hash , string $password , string $salt , int $bytes )
该函数根据参数password和salt返回一个单位为字节的key值,参数hash为要使用的算法。其中salt为一个固定8字节的值,如果用户给出的数值小于8字节,将用0补齐。
实例:
$filename = '08.txt'; $str = file_get_contents($filename); $hash = 2; $password = '111'; $salt = '1234'; $key = mhash_keygen_s2k(1,$password,$salt,10); $str_mhash = bin2hex(mhash($hash,$str,$key)); echo "文件08.txt的校验码是:".$str_mhash;
实例:使用OR,XOR等运算符,自定义一个加密函数:
<?php function encrpy($str,$key='key'){ $output; $num = strlen($str); for($i=0;$i<$num;$i++){ $tmp = substr($str,$i,1); $tmp = $tmp ^ $key; $tmp = ~$tmp; $output .= $tmp; } return $output; } function decrpy($str,$key='key'){ $output; $num = strlen($str); for($i=0;$i<$num;$i++){ $tmp = substr($str,$i,1); $tmp = ~$tmp; $tmp = $tmp ^ $key; $output .= $tmp; } return $output; } ?> <form method="post" action="#"> 请输入要加密的字串:<input name="str" type="text" /> <input name="encode" type="submit" value="加密" /> </form> <form method="post" action="#"> 请输入要解密的密文:<input name="str" type="text" /> <input name="decode" type="submit" value="解密" /> </form> <?php if($_POST['encode'] == '加密'){ echo '加密后的密文是:'.encrpy($_POST['str']); } if($_POST['decode'] == '解密'){ echo '解密后的明文是:'.decrpy($_POST['str']); } ?>
推荐phpass
密码加密之前一直使用md5方式,md5加密的密码是可以强行破解的,网上查询发现可以使用bcrypt算法,安全系数高,目前YII框架和wordpress都在使用这个算法。
phpass是一个开源的类库,可以让我们方便的使用bcrpt加密算法
官网:http://www.openwall.com/phpass/
具体实现代码如下:
// 引入类文件 require 'PasswordHash.php'; // 初始化散列器为不可移植,安全性更好。false加密字符串是60位,true加密字符是34位 $hasher = new PasswordHash(8, true); // 执行加密 $hashedPassword = $hasher->HashPassword('test123'); // 输出加密后的字符和对应的字符串长度 echo $hashedPassword; echo '<br>'; echo strlen($hashedPassword).'<br>'; // 检查密码是否正确,第一个参数是密码的明文,第二个是加密后的字符串 $hasher->CheckPassword('test123', $hashedPassword); // false $hasher->CheckPassword('test1234', $hashedPassword); // true
以上就介绍了 php的phpass类加密算法,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。
经 phpass 0.3 测试,在存入数据库之前进行哈希保护用户密码的标准方式。 许多常用的哈希算法如 md5,甚至是 sha1 对于密码存储都是不安全的, 因为骇客能够使用那些算法轻而易举地破解密码。
参考网址:
http://www.php.cn/php-weizijiaocheng-360353.html
http://www.php.cn/php-weizijiaocheng-360354.html
http://www.php.cn/php-weizijiaocheng-320395.html
转载请注明: ITTXX.CN--分享互联网 » php进阶--PHP加密扩展Mhash和Mcryp用法
最后更新:2019-03-28 16:54:03