的加解密是什么我们在做程序的时候,加解密是绕不开的话题。使用yii2开发应用时,内置的加解密(安全)支持有哪些?本文将为您揭晓。相关环境操作系统和IDEmacOS10.13.1&PhpStorm2018.1.2软件版本PHP7.1.8Yii2.0.14在yii2中管理加解密的库叫做Security,它以yii2组件的形式存在,所以可以使用Yii::$app->security获取和使用它。Security组件源码位置如下:vendor/yiisoft/yii2/base/Security.phpSecurity组件共有15个与加解密(&编码)相关的公共方法。我们先列一个清单。encryptByPasswordencryptByKeydecryptByPassworddecryptByKeyhkdfpbkdf2hashDatavalidateDatagenerateRandomKeygenerateRandomStringgeneratePasswordHashvalidatePasswordcompareStringmaskTokenunmaskToken我想你一定没见过,没关系,我们一一了解。generateRandomString之所以先说generateRandomString,是因为它最常用,至少我是这样的。公共函数generateRandomString($length=32){...}生成一个随机字符串,参数$length表示字符串的长度,默认为32位。值得注意的是,这个字符串的取值范围是[A-Za-z0-9_-]。generatePasswordHash&validatePasswordgeneratePasswordHash&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");echoYii::$app->security->encryptByPassword($dat,"3166886");//你好要注意,上面得到的编码数据不是ASCII,可以通过base64_encode和base64_decode在外层下进行封装。encryptByKey&decryptByKey也是一组编解码函数,比传密码快。该函数声明为publicfunctionencryptByKey($data,$inputKey,$info=null){}publicfunctiondecryptByKey($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的第三个参数表示生成的哈希值是否为原始二进制格式。如果为假,将生成一个小写的十六进制数。validateData检测已经加数据前缀的数据,如下代码所示$result=Yii::$app->security->validateData("ac28d602c767424d0c809edebf73828bed5ce99ce1556f4df8e223faeec60eddhello",'123456',false);//hello如果原来返回string,表示验证通过,否则返回false。validateData函数的第三个参数应该与使用hashData()生成数据时的值相同。表示数据中的哈希值是否为二进制格式。如果为false,则表示哈希值只由小写的十六进制数字组成。将生成十六进制数。compareString可以防止时序攻击字符串比较,使用非常简单。Yii::$app->security->compareString("abc",'abc');如果结果为真,则它们相等,否则它们不相等。那么什么是定时攻击呢?让我举一个简单的例子。if($code==Yii::$app->request->get('code')){}上面的比较逻辑,两个字符串从第一个字符开始一个一个比较,有则立即返回adifference为False,那么通过计算返回速度就可以知道是哪一位不同了,这样就实现了电影中经常出现的逐位破解密码的场景。但是使用compareString比较两个字符串,无论字符串是否相等,函数的耗时都是恒定的,可以有效防止时序攻击。maskToken&&unmaskTokenmaskToken用于屏蔽真正的token,不可压缩。相同的令牌在最后生成不同的随机令牌。yii2的csrf函数中使用了MaskToken。原理并不复杂。让我们看一下源代码。公共函数maskToken($token){$mask=$this->generateRandomKey(StringHelper::byteLength($token));returnStringHelper::base64UrlEncode($mask.($mask^$token));}而unmaskToken的用途也很明显,就是用来获取被maskToken屏蔽的token。接下来,让我们看一个示例代码$token=Yii::$app->security->maskToken("123456");echoYii::$app->security->unmaskToken($token);//结果最后是123456使用标准算法的密钥派生:pbkdf2()和hkdf();防止数据篡改:hashData()和validateData();密码验证:generatePasswordHash()和validatePassword()更多Yii原创文章
