Yii2.0安全之加密/解密

来源:互联网 发布:windows bat脚本sleep 编辑:程序博客网 时间:2024/05/29 11:04

LZ最近编写API接口时,应用到了安全验证(众所周知,接口的安全是非常重要的),因为使用的是Yii2.0框架,所以了解了一下Yii本身的加密/解密方法!!!此前也曾使用并总结API接口[详情版],不过缺少Token的使用,此处正好进行进一步的补充,也可查看了解Api接口的编写规范。

Yii提供了方便的助手功能,允许你使用安全密钥对数据进行加密/解密。数据通过加密函数传递,只有拥有密钥的人才能够解密它。

例如,我们需要在数据库中存储一些信息,但是我们需要确保只有拥有安全密钥的用户才能查看它(即使应用程序数据库泄露)。

1--操作方法

/** * 加密方法 * @param    String  $data      [要加密的数据] * @param    String  $secretKey [自己设置的密码] * @return   String             [加密结果] */$encryptedData = Yii::$app->getSecurity()->encryptByPassword($data, $secretKey); /** * 解密方法 * @param    String  $encryptedData      [要解密的数据] * @param    String  $secretKey [自己设置的加密时的密码] * @return   true|false             [解密结果] */$data = Yii::$app->getSecurity()->decryptByPassword($encryptedData,$secretKey);
[附加说明]
当我们利用encryptByPassword()对字符串加密时,会出现乱码,这可能会影响我们下一步的解密。
我们可以使用base64_encode()处理加密后的字符串,这样我们得到的密钥就只会由字母和数字组成。
ag:
$encryptedData = base64_encode(Yii::$app->getSecurity()->encryptByPassword($data, $secretKey));$data = Yii::$app->getSecurity()->decryptByPassword(base64_decode($encryptedData),$secretKey);

2--操作实例

API接口安全验证

2-0验证流程

首先通过登陆获取token,后续所有的API请求都需要携带此Token和用户ID,通过yii2.0自身的加密/解密算法对token进行验证,通过验证方可去请求数据。

2-1框架部署结构


2-2代码实例

2-2-0 params.php配置参数
<?phpreturn [    'adminEmail' => 'admin@example.com',    // TOKEN验证参数    'auth'=>[    //KEY值(MD5加密/可自定义)    'key'=>'f1e358c80759c68a37394c18755ba7de',      //密钥(可自定义)    'secret' =>'ningwang',     //有效期,单位为s。此处设置为2小时(可自定义)!!!时间不宜过长    'timeout'=>'7200'     ]];
【说明】此配置位于frontend/config/下

2-2-1 Token控制器

<?php namespace frontend\controllers;use Yii;use yii\web\Controller;/** * API安全验证 * @Author   NingWang * @DateTime 2017-12-15 * @version  [version 1.0.0] */class TokenController extends Controller{/** * 创建Token密钥 * @param    Int     $uid [用户ID] * @return   Str          [生成的Token密钥] */public function actionCreateToken($uid){#获取配置文件中Token验证参数$auth = yii::$app->params['auth'];  #获取当前时间[目的:设置时间超时机制]$nowTime = time();  #两次md5加密保证密钥安全性$secret = md5(md5($auth['secret'].$nowTime)); #设置加密数据[目的:拼接当前时间 & 传递参数]$data = $secret.'O_O'.$nowTime; #设置加密密码[目的:拼接用户ID,设置动态Key值]$secret = $auth['key'].$uid; #Yii加密算法生成Toekn(参数1:加密数据 参数2:自定义密码)$token = Yii::$app->getSecurity()->encryptByPassword($data,$secret);#由于生成的token乱码,我们可以base64加密,以便后续查看$token = base64_encode($token);return $token;}/** * 验证请求 * @param    Int     $uid   [用户ID] * @param    Str     $token [Token密钥] * @return   Json           [验证结果] */public function actionCheckToken($uid,$token){#获取配置文件中Token验证参数$auth = yii::$app->params['auth'];  #获取Token生成时的加密密码$secret = $auth['key'].$uid;#base64解码token$token = base64_decode($token);#Yii解密算法获取加密数据(参数1:Token 参数2:Token生成时设置的密码)#失败返回false,成功返回Token$data = Yii::$app->getSecurity()->decryptByPassword($token,$secret);if(!$data){$res = $this->error('600','Token验证失败');}else{$data = explode('O_O', $data);#检测Token数据完整性[包含加密密钥&时间]if(count($data)!=2){$res = $this->error('610','Token验证失败');}else{#检测时间超时机制if(time()-$data[1]>$auth['timeout']){$res = $this->error('620','Token已过期');}else{#检测加密密钥$secret = md5(md5($auth['secret'].$data[1]));if($secret == $data[0]){$res = $this->success();}else{$res = $this->error('630','密钥出错');}}}}return $res;}/**     * 成功信息     * @param Array $data 查询数据     * @return Array 返回请求页面数据     */    public function success($data='')    {        return array(            'code'  =>  '200',            'msg'   =>  'Token验证成功',            'data'  =>  $data        );    }    /**     * 错误信息     * @param Array $msg 提示消息     * @return Array 返回请求页面数据     */    public function error($code,$msg='查询失败',$data='')    {        return array(            'code'  =>  $code,            'msg'   =>  $msg,            'data'  =>  $data        );    }}?>

2-2-2 Login控制器

<?php namespace frontend\controllers;use yii;use frontend\controllers\TokenController;  #API安全验证控制器/** * 登陆模块 * @Author   NingWang * @DateTime 2017-12-15 * @version  [version 1.0.0] */class LoginController extends TokenController{public $enableCsrfValidation = false;  #关闭CSRF[为方便检测]/** * 登陆页面 * @return   Mix     [生成的Token] */public function actionLogin(){#这里假设用户ID为1[实际操作为用户登陆后数据库获取到用户ID]$uid = 1;#调取Token生成方法[传递参数用户UID]$token = $this->actionCreateToken($uid);#打印结果[包括状态码|提示消息|Token]var_dump($token);}}?>

2-2-3 Form控制器

<?php namespace frontend\controllers;use yii;use yii\web\Controller;/** * 表单模块 * @Author   NingWang * @DateTime 2017-12-15 * @version  [version 1.0.0] */class FormController extends Controller{/** *表单模拟页面 */public function actionForm(){return $this->render('form');}}?>

2-2-4 Find控制器

<?php namespace frontend\controllers;use yii;/** * 查询模块 * @Author   NingWang * @DateTime 2017-12-15 * @version  [version 1.0.0] */class FindController extends TokenController{public $enableCsrfValidation = false;  #关闭CSRF[为方便检测]//查询数据public function actionFind(){#检测是否为Post请求if(yii::$app->request->isPost){#获取参数$data = yii::$app->request->post();#安全认证(检测Token)$checkRes = $this->actionCheckToken($data['uid'],$data['token']);if($checkRes['code'] != 200){echo $checkRes['msg'];}else{echo "Token验证通过,进行后续数据库操作";}}else{#跳转表单页面return $this->render('../form/form');}}}?>
form.php页面
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>API检测接口</title></head><body><table><form action="?r=find/find" method="post"><tr><td>Token值:</td><td><input type="text" name="token" value="ning"></td></tr><tr><td>用户ID:</td><td><input type="text" name="uid" value="1"></td></tr><tr><td colspan="2" style="text-align: center;"><input type="reset" value="重置"><input type="submit" value="查询"></td></tr></form></table></body></html>

3--附加说明

在代码演示阶段,为快速简述此加解密方法,没有进行参数为空等安全方面的检测。
[参考资料]
1.http://blog.csdn.net/nw_ningwang/article/details/77876665
2.http://www.yii-china.com/post/detail/26.html
3.http://www.yiichina.com/doc/guide/2.0/security-cryptography