yii2的加密解密那些事儿

yii2的加密解密那些事儿

大家好,又见面了,我是你们的朋友全栈君。

我们做程序的时候,加密解密是绕不开的话题,使用yii2开发应用的时候,都内置了哪些有关加密解密(安全)方便的支持那?本文将为你揭晓。

相关环境

  • 操作系统及IDE macOS 10.13.1 & PhpStorm2018.1.2
  • 软件版本 PHP7.1.8 Yii2.0.14

在yii2中,管理加密解密的库叫做Security,它以yii2组件的形式存在,因此你可以通过Yii::$app->security来获取并使用它。

Security组件源代码位置如下

vendor/yiisoft/yii2/base/Security.php

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

  1. encryptByPassword
  2. encryptByKey
  3. decryptByPassword
  4. decryptByKey
  5. hkdf
  6. pbkdf2
  7. hashData
  8. validateData
  9. generateRandomKey
  10. generateRandomString
  11. generatePasswordHash
  12. validatePassword
  13. compareString
  14. maskToken
  15. 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

最后我们总结下

  • 加密/解密: encryptByKey()、decryptByKey()、 encryptByPassword() 和 decryptByPassword();
  • 使用标准算法的密钥推导: pbkdf2() 和 hkdf();
  • 防止数据篡改: hashData() 和 validateData();
  • 密码验证: generatePasswordHash() 和 validatePassword()

更多Yii原创文章

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107477.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • NOVO SOP (SOP简介及历史)[通俗易懂]

    NOVO SOP (SOP简介及历史)[通俗易懂]SOP(StandardOperationProcedure),标准作业程序。一、什么是SOP(标准作业程序)  所谓SOP,是StandardOperationProcedure三个单词中首字母的大写,即标准作业程序(标准操作程序),就是将某一事件的标准操作步骤和要求以统一的格式描述出来,用来指导和规范日常的工作。  SOP的精髓,就是将细节进行量化,用更通俗的话来…

    2022年5月25日
    33
  • Python语法详解

    Python语法详解python语法解析Python的结构有三种:顺序结构、分支结构、循环结构。一、顺序结构具体结构如下:顺序结构比较简单,就是按照代码的顺序从上到下执行,这是Python最基本的程序执行结构,也

    2022年7月5日
    32
  • 展频技术是如何搞定时钟信号的辐射的呢_辐射电磁波的频率

    展频技术是如何搞定时钟信号的辐射的呢_辐射电磁波的频率先前我们说了说:为什么时钟信号比数据信号更容易引起辐射超标?为什么时钟信号比数据信号更容易引起辐射超标?并且做了试验,如果认真看过的话,就会明白,周期性的信号是窄带频谱,特定的频率的幅值会很高,这对认证测试来说非常的不利。而一般时钟信号都是周期信号,这在电路中是少不了的。有没有什么办法,改造下时钟的频谱,同时又不影响功能呢?答案是有的,那就是展频技术。展频技术的应用展频技术经常用于解决辐射问题,比如我们前面说的音频功放,需要接LC滤波器。就有的厂家通过展频技术,推出不需要LC滤波器.

    2025年7月25日
    1
  • 上delloc 无呼叫 故障排除 笔记[通俗易懂]

    上delloc 无呼叫 故障排除 笔记

    2022年1月17日
    42
  • python输出保留小数位_python保留两位小数补0

    python输出保留小数位_python保留两位小数补0前言保留小数位是我们经常会碰到的问题,尤其是刷题过程中。那么在python中保留小数位的方法也非常多,但是笔者的原则就是什么简单用什么,因此这里介绍几种比较简单实用的保留小数位的方法:方法一:format函数>>>print(‘{:.3f}’.format(1.23456))1.235>>>print(format(1.23456,’.2f’))1.23正如上面代码所示,format有不同用…

    2022年8月12日
    6
  • 基于stm32的室内环境监测系统设计及实现_毕业设计怎么做

    基于stm32的室内环境监测系统设计及实现_毕业设计怎么做一、前言这是本科时的毕业设计,想着之后读研了,研究方向是机器学习了,可能不会这么再碰32或者51之类的板子了,就想趁着还没有忘记就来梳理一下,纪念陪伴了我两年的硬件朋友们,作为的一个足迹。二、项目背景及资源分享这次毕业设计的灵感来源于20年的电赛,当时因为考研时间紧张的原因,在做一个《无线传感器结点》题目的时候,当时是使用的无线传感器模块讲数据传到电脑作为一个上位机的展示。但当时想做的是使用wifi模块来实现无线传输功能,传到一个自己写的web服务器,在页面上进行展示的,由于时间原因最终还是选择了前者

    2022年9月1日
    4

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号