使用yii2怎么实现加密解密
创始人
2024-12-07 16:01:47
0次

Security组件源代码位置如下

vendor/yiisoft/yii2/base/Security.php

Security组件一共有15个与加密解密(&编码)相关的公共方法,我们先来列一个清单。

  • encryptByPassword

  • encryptByKey

  • decryptByPassword

  • decryptByKey

  • hkdf

  • pbkdf2

  • hashData

  • validateData

  • generateRandomKey

  • generateRandomString

  • generatePasswordHash

  • validatePassword

  • compareString

  • maskToken

  • unmaskToken

我想有一些你一定没见过,没关系,我们一一去了解。

generateRandomString

之所以先说generateRandomString是因为它最常用,起码我是这样。

public function generateRandomString($length = 32){...}

生成一个随机的字符串,参数$length代表这个字符串的长度,默认32位。值得说明的是这个字符串的取值为范围是[A-Za-z0-9_-]。

generatePasswordHash & validatePassword

generatePasswordHash & validatePassword经常被用来加密用户密码以及对密码是否正确的验证,自从MD5可能被碰撞后,我们用yii2开发应用的时候,generatePasswordHash函数对密码进行加密就成为首选了,它调用了crypt函数。

一般用法如下

// 使用generatePasswordHash为用户的密码加密,$hash存储到库中
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);

// 使用validatePassword对密码进行验证
if(Yii::$app->getSecurity()->validatePassword($password, $hash)){
 // 密码正确
}else{
 // 密码错误
}

generateRandomKey

和generateRandomString类似,生成一个随机的串,参数为长度,默认为32位,区别在于generateRandomKey生成的不是ASCII。

简单的说 generateRandomString 约等于 base64_encode(generateRandomKey)。

encryptByPassword & decryptByPassword

编码和解码函数,使用一个秘钥对数据进行编码,然后通过此秘钥在对编码后的数据进行解码。

例子

$dat = Yii::$app->security->encryptByPassword("hello","3166886");
echo Yii::$app->security->encryptByPassword($dat,"3166886");// hello

要注意,通过上面得到的编码后的数据不是ASCII,可以通过base64_encode和base64_decode在外层包装下。

encryptByKey & decryptByKey

同样是一组编码和解码函数,比通过密码的方式要快。函数声明为

public function encryptByKey($data, $inputKey, $info = null){}

public function decryptByKey($data, $inputKey, $info = null){}

encryptByKey & decryptByKey 存在着第三个参数,比如我们可以传递会员的ID等,这样此信息将和$inputKey一起作为加密解密的钥匙。

hkdf

使用标准的 HKDF 算法从给定的输入键中导出一个键。在PHP7+使用的是hash_hkdf方法,小于PHP7使用hash_hmac方法。

pbkdf2

使用标准的 PBKDF2 算法从给定的密码导出一个密钥。该方法可以用来进行密码加密,不过yii2有更好的密码加密方案 generatePasswordHash。

hashData和validateData

有的时候为了防止内容被篡改,我们需要对数据进行一些标记,hashData和validateData就是完成这个任务的组合。

hashData 用来对原始数据进行加数据前缀,比如如下代码

$result = Yii::$app->security->hashData("hello",'123456',false);
// ac28d602c767424d0c809edebf73828bed5ce99ce1556f4df8e223faeec60eddhello

你看到了在hello的前面多了一组字符,这组字符会随着原始数据的不同而变化。这样我们就对数据进行了特殊的防止篡改标记,接下来是validateData上场了。

注意:hashData的第三个参数代表生成的哈希值是否为原始二进制格式. 如果为false, 则会生成小写十六进制数字.

validateData 对已经加了数据前缀的数据进行检测,如下代码

$result = Yii::$app->security->validateData("ac28d602c767424d0c809edebf73828bed5ce99ce1556f4df8e223faeec60eddhello",'123456',false);
// hello

如果返回了原始的字符串则表示验证通过,否则会返回假。

validateData 函数的第三个参数应该与使用  hashData() 生成数据时的值相同. 它指示数据中的散列值是否是二进制格式. 如果为false, 则表示散列值仅由小写十六进制数字组成. 将生成十六进制数字.

compareString

可防止时序攻击的字符串比较,用法非常简单。

Yii::$app->security->compareString("abc",'abc');

结果为真则相等,否则不相等。

那么什么是时序攻击那?我来举一个简单的例子。

if($code == Yii::$app->request->get('code')){
 
}

上面的比较逻辑,两个字符串是从第一位开始逐一进行比较的,发现不同就立即返回 false,那么通过计算返回的速度就知道了大概是哪一位开始不同的,这样就实现了电影中经常出现的按位破解密码的场景。

而使用 compareString 比较两个字符串,无论字符串是否相等,函数的时间消耗是恒定的,这样可以有效的防止时序攻击。

maskToken && unmaskToken

maskToken用于掩盖真实token且不可以压缩,同一个token最后生成了不同的随机令牌,在yii2的csrf功能上就使用了maskToken,原理并不复杂,我们看下源码。

public function maskToken($token){
 $mask = $this->generateRandomKey(StringHelper::byteLength($token));
 return StringHelper::base64UrlEncode($mask . ($mask ^ $token));
}

而unmaskToken目的也很明确,用于得到被maskToken掩盖的token。

接下来我们看一个例子代码

$token = Yii::$app->security->maskToken("123456");
echo Yii::$app->security->unmaskToken($token);// 结果为 123456

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...