进击微信小程序 AES交互加密

最近在开发微信小程序;
涉及到请求接口数据加密的问题;
用的是laravel 框架;
话不多说直接上代码;
这是 laravel 中间件;
参考了微信根据session_key解密用户信息;
来 , 看图说话;
ase交互流程图
php代码:

<?php
namespace App\Http\Middleware;

use Closure;

/**
 * Class verifySign
 * @package App\Http\Middleware
 * @author shidatuo
 * @description 参数加密
 */
class verifySign
{
    /**
     * @var string 解密的密钥 , 和小程序需要保持aeskey保持一致
     */
    protected $privateKey = 'zxcvbnmasdfghjkl';

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next){

        // 解密参数
        $params = self::verifySign(
            request()->input('encryptedData',''), // 加密参数
            request()->input('iv','') //随机字符串iv
        );

        // 合并request 对象里面的参数
        $request->merge($params['data']);

        // 返回下一步
        return $next($request);

    }

    /**
     * @param $encryptedData
     * @param $iv
     * @return array
     * @author shidatuo
     * @description 验证签名 + 解密
     */
    private function verifySign($encryptedData,$iv){

        // 验证参数
        if(empty($encryptedData) || empty($iv))
            return ['code'=>400,'msg'=>'缺少必传参数','data'=>[]];

        // 解密参数
        $encryptedData = rawurldecode(urlencode($encryptedData));

        // base64解密
        $encryptedData = base64_decode($encryptedData);

        // 非对称解密
        $decrypted = @openssl_decrypt($encryptedData,'AES-128-CBC', $this->privateKey, OPENSSL_RAW_DATA, $iv);

        if(!$decrypted)
            return ['code'=>400,'msg'=>'参数解密失败','data'=>[]];

        return ['code'=>200,'msg'=>'获取成功','data'=>json_decode($decrypted,true)];
    }
}

然后再把这个中间间加入到路由中间件里面;

/**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
        'can' => \Illuminate\Auth\Middleware\Authorize::class,
        'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
        'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
        // 加入到路由中间件里面
        'verifySign'=>\App\Http\Middleware\verifySign::class,
    ];

这样哪些接口需要解密;
在路由里面增加此中间件就行啦;
小程序代码:

// util 文件
var aes = require('aes.min.js'); //引入aes类包
//URl: https://github.com/wzqwzq666/JS_AESencode/blob/master/utils/aes.js

//十六位十六进制数作为秘钥
var aeskey = aes.CryptoJS.enc.Utf8.parse("zxcvbnmasdfghjkl");
//十六位十六进制数作为秘钥偏移量
var aesiv = aes.CryptoJS.enc.Utf8.parse('mnbvcxzlkjhgfdae');

// 加密
function encrypt(data) {
    var srcs = aes.CryptoJS.enc.Utf8.parse(data);
    var encrypted = aes.CryptoJS.AES.encrypt(srcs, aeskey, { iv: aesiv, mode: aes.CryptoJS.mode.CBC, padding: aes.CryptoJS.pad.Pkcs7 });
    //返回base64加密结果
    return encrypted.toString();
}

//解密
function decrypt(data) {
   // data是base64编码数据
    var decrypt = aes.CryptoJS.AES.decrypt(data, aeskey, { iv: aesiv, mode: aes.CryptoJS.mode.CBC, padding: aes.CryptoJS.pad.Pkcs7 });
    var decryptedStr = decrypt.toString(aes.CryptoJS.enc.Utf8);
    return decryptedStr.toString();
}

return {
     encrypt: encrypt,
     decrypt: decrypt
}

求知欲

史大坨博客
请先登录后发表评论
  • 最新评论
  • 总共0条评论