【PHP】PHP中加密函数的应用

一、前言。

先简单说下概念。加密分为以下几种:对称式加密算法、非对称式加密算法。这2个概念,这里就不细说了。简单说下,我们经常遇到的单向加密、双向加密。

单向加密,通常认为在单位有效时间内无法解密,属于单向加密的算法。双向加密就是可以同时解密。

所以,下面我们不会讲解对称加密算法、非对称加密算法了。只从是否可以有效时间内解密这个维度来讲。


二、单向加密算法。

2.1、MD5。

我们通常存储在数据库中的密码,是通过MD5加密的。有些接口请求,也是采用MD5进行签名再加密。

$str = 'ligang';
// c513dea20611d0ce598bf6f93fb4bed5
echo 'MD5加密后的字符串:'. MD5($str), PHP_EOL;
// len = 32
echo strlen(MD5($str));
md5加密后的字符串都是32位长度的,包含大小写字母、数字的字符串。


2.2、Sha1。

$str = 'ligang';
// 879e6a8cc4b8f0fca34b20faaa7f0edb6ac2f3bc
echo 'sha1加密后的字符串:'. sha1($str), PHP_EOL;
// len = 40
echo strlen(sha1($str));

我们可以看到sha1函数加密后的字符串长度更长,有40位。

更多关于PHP中sha1函数,请看:sha1散列函数详解


三、双向加密算法。

3.1、URL编码加密。

$str = 'ligang\124234';
// ligang%5C124234
echo 'url加密后的字符串:'. urlencode($str), PHP_EOL;
// ligang\124234
echo urldecode(urlencode($str));

我们可以看到,这个函数实际上对于普通的字符、数字,没有做什么处理。只是对于有关url的特殊字符串进行了编码。

所以,当我们传输给后端的参数里如果带有特殊字符,需要进行urlencode编码。


3.2、base64编码加密。

$data="I am king";
// SSBhbSBraW5n
echo base64_encode($data);
echo PHP_EOL;
// I am king
echo base64_decode(base64_encode($data));

这个编码函数通常用在对于长字符串、图片进行编码。可以反向解码。有点类似于压缩函数。


3.3、mcrypt_encrypt、mcrypt_decrypt加密、解密函数。

$cipher = MCRYPT_DES;
$modes = MCRYPT_MODE_ECB;
$key = 'F293N@#!';
$iv = mcrypt_create_iv(mcrypt_get_iv_size($cipher, $modes), MCRYPT_RAND);//初始化向量
$token = urlencode(mcrypt_encrypt($cipher, $key, $token, $modes,$iv));  //加密函数
PubFileLog::writeDebugInfo('加密密文:' . $token);
$str_decrypt = mcrypt_decrypt($cipher, $key, urldecode($token), $modes,$iv);  //解密函数
PubFileLog::writeDebugInfo('解密密文:' . $str_decrypt);

以上,加密、解密函数的使用流程,在PHP5.6、PHP5.3中,都可以兼容使用。

注意:mcrypt_encrypt这个函数在PHP7.1中,已经删除了,具体请看:mcrypt_encrypt函数详解

Warning: This function has been DEPRECATED as of PHP 7.1.0. Relying on this function is highly discouraged.

5.6.0 Invalid key and iv sizes are no longer accepted. mcrypt_encrypt() will now throw a warning and return FALSE if the inputs are invalid. Previously keys and IVs were padded with '\0' bytes to the next valid size.

在5.6中,key的字符串长度不要超过8。


3.4、在PHP7.1中,3.3中加密函数已经没有了,现在怎么办呢。我们可以自己写。

下面的链接是开发微信公众号时,官方提供的加密解密函数的文档(百度云链接)。具体官方的链接已经难以找到了。

链接:进入百度网盘 密码:o4a7

其实,我们弄懂了几种非对称、对称加密算法后,可以自己写。

AES加密算法详解 、微信公众平台开发者中心安全模式消息体加解密实现


3.5、PHP7.1中,丢弃了mcrypt_encrypt,但是新加入了openssl_encrypt。这个扩展在某些低版本中也是存在的。

(1)简单应用,不使用iv的情况。

$textToEncrypt = "My super secret information.";
$encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents.
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";

//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash);

//To Decrypt
$decryptedMessage = openssl_decrypt($encryptedMessage, $encryptionMethod, $secretHash);

//Result
echo "加密: $encryptedMessage \n原文: $decryptedMessage";

(2)使用iv的情况。iv有点类似于掩码,可以做到随机,每次都不一样。

$textToEncrypt = "My super secret information.";
$encryptionMethod = "AES-256-CBC";  // AES is used by the U.S. gov't to encrypt top secret documents.
$secretHash = "25c6c7ff35b9979b151f2136cd13b0ff";
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
//To encrypt
$encryptedMessage = openssl_encrypt($textToEncrypt, $encryptionMethod, $secretHash, 0, $iv);

$encryptedMessage = $iv . $encryptedMessage; // union and save to the db
//To Decrypt
$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
$iv = substr($encryptedMessage, 0, $iv_size);
$decryptedMessage = openssl_decrypt(substr($encryptedMessage, $iv_size), $encryptionMethod, $secretHash, 0, $iv);

//Result
echo strlen($encryptedMessage), PHP_EOL;
echo "加密: $encryptedMessage \n原文: $decryptedMessage";


下面代码是我的写法,再存入数据库时最好是用base64_encode加密下,要不然'乱码'可能存不了数据库。

function myEncrypt($str, $hash='25c6c7ff35b9979b151f2136cd13b0ff', $method='AES-256-CBC') {
    if ( !function_exists('openssl_encrypt') ) {
        throw new RuntimeException('不存在openssl模块', PubReCode::$IllegalParametersError);
    }
    $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
    $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
    // To encrypt
    $encrypted_message = openssl_encrypt($str, $method, $hash, 0, $iv);
    // union and save to the db or file
    $encrypted_message = $iv . $encrypted_message;
    return base64_encode($encrypted_message);
}
function myDecrypt($str, $hash='25c6c7ff35b9979b151f2136cd13b0ff', $method='AES-256-CBC') {
	if ( !function_exists('openssl_encrypt') ) {
		throw new RuntimeException('不存在openssl模块', PubReCode::$IllegalParametersError);
	}
	$str = base64_decode($str);
	$iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
	$iv = substr($str, 0, $iv_size);
	// To Decrypt
	$decrypted_message = openssl_decrypt(substr($str, $iv_size), $method, $hash, 0, $iv);
	return $decrypted_message;
}



四、总结。

其实,严格意义上来讲,2.1、2.2、3.1、3.2都算不上是加密函数。

2.1、2.2严格以上来讲是属于散列(hash)函数。3.1、3.2属于一种编码手段。

真正意义上的加密解密函数,是必须是一对的,而且,有秘钥的情况下,是可以解密的。

只是这种秘钥分为两种情况,就是前言里说的,对称加密、非对称加密的区别。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值