欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微信小程序使用AES加密和解密

程序员文章站 2024-03-14 15:47:40
...

前端请求后端接口进行参数加密处理:

const CryptoJs = require('crypto-js');
const defaultKey = "zoe_nurse_qazxr8"; // 默认的key
const defaultIv = "qwertyuiopasdfgh"; // 默认的key 偏移量

/**
 * 加密方法
 * @param: str 需要加密的字符
 * @param: key **
 * @param: iv **偏移量
 */
function encrypt(str, key, iv) {
    const keyStr = key ? encParse(key) : encParse(defaultKey);
    const ivStr = iv ? encParse(iv) : encParse(defaultIv);
    
    const encryptedStr = CryptoJs.AES.encrypt(str, keyStr, {
        iv: ivStr,
        mode: CryptoJs.mode.CBC,
        padding: CryptoJs.pad.Pkcs7
    });
    
    // 直接toString()是base64格式的字符串
    // ciphertext.toString() 是128位的字符串
    return encryptedStr.toString();
}
/**
 * 解密方法
 * @param: str 需要解密的字符
 * @param: key **
 * @param: iv **偏移量
 */
function decrypt(str, key, iv) {
    const keyStr = key ? encParse(key) : encParse(defaultKey);
    const ivStr = iv ? encParse(iv) : encParse(defaultIv);
    
    // 判断str是否为base64,如果不是就要转base64,是了就不能再转
    const flag = isBase64(str);
    if (!flag) {
        // 转为base64之前要先转16进制
        str = CryptoJs.enc.Hex.parse(str);
        // 只有base64格式的字符才能被解密
        str = CryptoJs.enc.Base64.stringify(str);
    }
    
    const encryptedStr = CryptoJs.AES.decrypt(str, keyStr, {
        iv: ivStr,
        mode: CryptoJs.mode.CBC,
        padding: CryptoJs.pad.Pkcs7
    });
    return encryptedStr.toString(CryptoJs.enc.Utf8);
}
/**
 * 处理**字符格式
 * @param: key 需要转格式的字符
 */
function encParse(key) {
    // key = CryptoJs.enc.Utf8.parse(key);
    return CryptoJs.enc.Latin1.parse(key);
}
/**
 * 使用MD5 hash字符串
 * @param: str 需要加密的字符串
 * @param: times 需要hash的次数
 */
function md5(str, times = 1) {
    for (let i = 0; i < times; i++) {
        str = CryptoJs.MD5(str).toString();
    }
    return str;
}
/**
 * 判断是否是Base64格式的字符串
 */
function isBase64(str) {
    let reg = /^(([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=))|(([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{2}==))$/;
    return reg.test(str);
}

export default {
    decrypt,
    encrypt,
    md5
}

在request请求里使用

import api from './api';
import cryptoJs from './aes.js'

const APP_CONFING = api.getAppConfig();

/**
 * 登录拦截
 * @param {String} resolve 成功
 * @param {String} reject 失败
 * @param {String} data 返回数据
 * @return {function} promise
 */
function loginRequest(resolve, reject, data) {
    reject(data || '请先登录');
    let dataRouter = api.getRouterMin();
    if (dataRouter.router === '/pages/login/index') {
        api.removeStorage('Router');
        api.redirectPage('/pages/login/index')
    } else {
        api.setStorage('Router', JSON.stringify(dataRouter));
        api.redirectPage('/pages/login/index')
    }
}

/**
 * 发送请求
 * @param {Object} options
 * @param {String} options.url 请求地址
 * @param {String} options.method 请求方式
 * @param {String} options.data 入参
 * @param {String} options.loading 请求地址
 * @param {String} options.loadingText 请求地址
 * @param {String} options.whiteAuth 是否是白名单
 * @return {function} promise
 */
function beforeRequest(options) {
    return new Promise((resolve, reject) => {
        let token = APP_CONFING.TOKEN;
        let header = APP_CONFING.HEADER;
        // 判断是否需要登录权限(默认需要登录权限)
        if (!options.whiteAuth === true && !token) {
            loginRequest(resolve, reject, '请先登录');
            return
        }
        // 判断是否显示加载框
        if (options.loading) {
            wx.showLoading({
                title: options.loadingText || '加载中'
            });
        }
        if(token){
            header['token'] = token;
        }
        header['requestId'] = new Date().getTime();
        options.data = {
            userId: APP_CONFING.USER_INFO.userId,
            userImCode: APP_CONFING.TOKEN_TIM.IM_ID,
            patientId: APP_CONFING.TOKEN_TIM.IM_ID && APP_CONFING.TOKEN_TIM.IM_ID.replace(/[^0-9]/ig, ""),
            ...options.data
        };
        options.data = APP_CONFING.ENCRY ? cryptoJs.encrypt(JSON.stringify(options.data)) : options.data;
        options.header = header;
        afterRequest(options, resolve, reject)
    })
}

/**
 * 发送请求
 * @param {Object} options
 * @param {String} options.url 请求地址
 * @param {String} options.method 请求方式
 * @param {String} options.data 入参
 * @param {String} options.header 请求头部
 * @param {String} options.loading 请求地址
 * @param {String} options.loadingText 请求地址
 * @param {String} options.whiteAuth 是否是白名单
 * @param {String} resolve 成功
 * @param {String} reject 失败
 * @return {function} promise
 */
function afterRequest(options, resolve, reject) {
    wx.request({
        url: options.url,
        method: options.method,
        header: options.header,
        data: options.data,
        timeout: 30000,
        success: (res) => {
            let data = res.data;
            // if (APP_CONFING.ENCRY) {
            //     //解密并去除空格和换行符
            //     let x = cryptoJs.decrypt(data).replace(/[ ]|[\r\n]/g, "");
            //     //展现多余的u0000
            //     x = JSON.stringify(x).replace(/[\\]/g, '');
            //     //去除u0000
            //     x = x.replace(new RegExp('u0000', "gm"), '');
            //     //截取JSON字符串对象
            //     x = x.substring(1, x.length - 1);
            //     //转为JSON对象
            //     data = JSON.parse(x);
            //     api.log('回参', data)
            // }
            let {
                code,
                message
            } = data;
            // 正常状态码的响应处理
            if (code === "200") {
                resolve(data, res);
            }
            // 特殊错误状态码的响应处理
            else if (['401', '402'].indexOf(code) !== -1) {
                reject(data);
            }
            // 信息过期需要重新登录的特殊状态码响应处理
            else if (['410000', '410001', '410002', '40000'].indexOf(code) !== -1) {
                loginRequest(resolve, reject, data);
            } else {
                reject(message || '服务器错误');
            }
        },
        fail: (err) => {
            reject(err);
            api.log("加载失败", err)
        },
        complete: (message) => {
            if (options.loading) {
                wx.hideLoading();
            }
        }
    })
}

const request = {};

// 设置请求方式(BASE_URL)
['options', 'get', 'post', 'put', 'head', 'delete'].forEach((method) => {
    request[method] = (options = {}) => {
        options.url = `${APP_CONFING.BASE_URL}${options.url}`;
        return beforeRequest({method, ...options})
    }
});

module.exports = request;