欢迎您的光临,本博所发布之文章皆为作者亲测通过,如有错误,欢迎通过各种方式指正。由于本站位于香港虚拟主机,故速度比较慢。

教程  php进阶--PHP加密扩展Mhash和Mcryp用法

PHP工具扩展 本站 197 0评论

在开发中,很多时候我们在前后端交互中需要对一些敏感数据进行一定的加密。PHP中有提供了mcrypt的这样一个加密扩展实现对数据的加密解密。


1.Mcrypt扩展库


官网:http://php.net/manual/zh/book.mcrypt.php 

在低版本的PHP中需要在配置文件php.ini中显式添加对扩展的引用,同时要保证扩展引用目录中有相应的扩展文件;在高版本的PHP中,Windows下似乎默认开启了mcrypt的扩展,既不需要在配置文件php.ini中做配置,在扩展引用目录中也没有看到相应的扩展文件,在linux下则需要安装对应的mcrypt.so扩展。

111.jpg


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." ";
}
?>

输出:

22.jpg


这些算法和模式在实际应用中要常用常量来表示,写到时候分别加上前缀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 的名称
}
?>

输出:

333.jpg

注意:如果在实际应用中使用上面的常量,需要在算法名称前面加上 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

赞 (1) or 分享 ()
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽