精华内容
下载资源
问答
  • 后端egg和前端vue分离开发接口验签

    千次阅读 2019-01-30 11:29:37
    在做前后台分离开发管理系统的时候,碰到了接口加密的问题,接口加密什么鬼?大概网上看了一下验签,md5加密,慢慢有思路了。 前端 前后台协商接口提供出appid(用户标识)和appsecret(应用秘钥) 前端根据appid和...

    在做前后台分离开发管理系统的时候,碰到了接口加密的问题,接口加密什么鬼?大概网上看了一下验签,md5加密,慢慢有思路了。

    前端

    • 前后台协商接口提供出appid(用户标识)和appsecret(应用秘钥)
    • 前端根据appid和appsecret以及请求参数,按照一定算法生成签名sign
    • 接口提供方验证签名
    生成签名的步骤如下
    1. 将所有业务请求参数按字母先后顺序排序
    2. 参数名称和参数值链接成一个字符串A
    3. 在字符串A的首尾加上appsecret组成一个新字符串B
    4. 对字符串进行md5得到签名sign

    假设请求的参数为:f=1,b=23,k=33,排序后为b=23,f=1,k=33,参数名和参数值链接后为b23f1k33,首尾加上appsecret后md5:
    md5(secretkey1value1key2value2…secret)。

    具体使用方式
    export const appid = '39387298290402342341' // 标识用户
    export const appsecret =  '$aJ3*&'   // 用来使用此约定加密规则,提高安全性
    
    import {appid, appsecret} from '../../assets/js/encrypt'  
    
    let time = new Date().getTime()  // 获取当前时间戳,后端用来限制请求次数
    // 通过自定义规则结合秘钥加密处理
    const sign = md5(appsecret+'FertSiteID24PageIndex1PageSize2'+appsecret)
    
    // get方法
    this.$http.get('/api/Check.ashx', {
        params: {
            FertSiteID: 24,
            PageIndex: 1,
            PageSize: 2,
            sign, // 将签名传递到后台
            time // 将时间戳传到后台
        }
    }).then((res) => {
        console.log(res.data)
    }).catch((e) => {
        console.log('请求失败'+e) 
    })
    还可以提前约定的appid用户标识传到后台
    // http://localhost:8081/api/Check.ashx?FertSiteID=24&PageIndex=1&PageSize=2&sign=c846b7dccecb5dd8a080ea54a0bdae2c&time=1548815454871
    

    后端

    后端通过传递过来的参数根据之前约定的appid,appsecret和签名的自定义算法进行相应的判断,如果一致,则返回成功,否则失败

    问题的重点:安全性的思考

    • appid,appsecret和签名的自定义算法如何不被泄露,是此操作的重点。
    • 其中核心的东西是appsecret应用秘钥,只要这个不泄露,知道其他的都无防
    • 以上东西放到服务器上别人肯定是看不到的
    • 但是重点是在前端,我们知道前端的东西都是不安全的,万一appsecret泄露了怎么办?
    • 因为此项目是egg结合vue开发的前后端分离项目,egg只负责提供接口,此接口所有人都可以访问,前端vue项目独立。
    • 前端项目是vue+webpack开发的项目,所有之后发布肯定是发布打包之后dist目录下的文件,但是发布之后在浏览器端会看到webpack里面vue的所有源文件,解决办法:去src/config/index.js中改一个参数:productionSourceMap:false 把这个改为false。然后重新打包发布
    • map文件的作用:项目打包后,代码都是经过压缩加密的,如果运行时报错,输出的错误信息无法准确得知是哪里的代码报错。 有了map就可以像未加密的代码一样,准确的输出是哪一行哪一列有错。
    • 所以有了这样的操作前端就不需要担心泄露应用秘钥问题
    • 还有webpack也可以加密相关的文件,可以多多了解
    展开全文
  • 需求背景 前端参数传至后端,需要加密参数,以防止被爆破和信息泄漏。又因为是暴露给外部使用的...前端vue解决方案 首先我们使用 crypto-js加密类库 1)安装 cnpm install crypto-js --save 此外使用淘宝的...

    需求背景

    前端参数传至后端,需要加密参数,以防止被爆破和信息泄漏。又因为是暴露给外部使用的接口,无法使用oath2等内部权限

    技术栈

    前端使用vue开发。后端主要使用java开发。加密方案使用AES算法。 base64。

    解决方案

    前端vue解决方案

    首先我们使用 crypto-js加密类库

    1)安装

    cnpm install crypto-js --save
    

    此外使用淘宝的cnpm, 下载速度快。若没有安装淘宝此包。直接使用npm也是可以的
    2) 写一个通用工具js

    /**
     * AES工具类
     */
    import CryptoJS from 'crypto-js'
    const aeskey = "crm25sqdc58start";
    
    const KEY = CryptoJS.enc.Utf8.parse("zhelixie16weimim"); //""中与后台一样  密码
    const IV = CryptoJS.enc.Utf8.parse("zhelixie16weimim"); //""中与后台一样
    export default { //加密
      encrypt(word) {
        let key = KEY
        let iv = IV
        let srcs = CryptoJS.enc.Utf8.parse(word);
        var encrypted = CryptoJS.AES.encrypt(srcs, key, {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.ZeroPadding
        });
        // console.log("-=-=-=-", encrypted.ciphertext)
        return CryptoJS.enc.Base64.stringify(encrypted.ciphertext);
      },
      //解密
      decrypt(word) {
        let key = KEY
        let iv = IV
        let base64 = CryptoJS.enc.Base64.parse(word);
        let src = CryptoJS.enc.Base64.stringify(base64);
    
        var decrypt = CryptoJS.AES.decrypt(src, key, {
          iv: iv,
          mode: CryptoJS.mode.CBC,
          padding: CryptoJS.pad.ZeroPadding
        });
    
        var decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
        return decryptedStr.toString();
      }
    
    }

     3)调用

    import AesUtil from "@/utils/aes-util";
    
    ...
    
    let encryLink = AesUtil.encrypt(this.userInfo.userId);
    
    let deencryLink = AesUtil.decrypt(encryLink);

    如果是放在url里的参数,还需要对整个uri encode或对参数encode,不然如果里面有加号等特殊符号,后端收到会出现问题。

    this.link =
            this.link +
            "?param=" +
            encodeURIComponent(AesUtil.encrypt(this.userInfo.userId));

     后端Java解决方案

    1)引入base64依赖

    <dependency>
    			<groupId>commons-net</groupId>
    			<artifactId>commons-net</artifactId>
    			<version>3.0.1</version>
    		</dependency>

    2)写一个util类

     package com.bj58.crm.sqdc.util;  
      
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.commons.net.util.Base64;  
      
      
    /** 
     * AES工具类 
     * @author paymoon.com @不止鱼
     * <pre> 
     *   因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件。 
     *   替换的文件:%JDK_HOME%\jre\lib\security\local_policy.jar 
     * 参考: http://czj4451.iteye.com/blog/1986483 
     */  
    public class AESUtil {  
        // 密钥  
        public static String key = "zhelixie16weimim";  
        private static String charset = "utf-8";  
        // 偏移量  
        private static int offset = 16;  
        private static String transformation = "AES/CBC/NoPadding";  
        private static String algorithm = "AES";  
      
        /** 
         * 加密 
         *  
         * @param content 
         * @return 
         */  
        public static String encrypt(String content) {  
            try {
    			return encrypt(content, key);
    		} catch (Exception e) {
    		}
    		return null;  
        }  
      
        /** 
         * 解密 
         *  
         * @param content 
         * @return 
         */  
        public static String decrypt(String content) {  
            return decrypt(content, key);  
        }  
      
        /** 
         * 加密 
         *  
         * @param content 
         *            需要加密的内容 
         * @param key 
         *            加密密码 
         * @return 
         */  
    //    public static String encrypt(String content, String key) {  
    //        try {  
    //            SecretKeySpec skey = new SecretKeySpec(key.getBytes(Charset.forName("UTF-8")), algorithm);  
    //            IvParameterSpec iv = new IvParameterSpec(key.getBytes(Charset.forName("UTF-8")), 0, offset);  
    //            Cipher cipher = Cipher.getInstance(transformation);  
    //            byte[] byteContent = content.getBytes(charset);  
    //            cipher.init(Cipher.ENCRYPT_MODE, skey, iv);// 初始化  
    //            byte[] result = cipher.doFinal(byteContent);  
    //            return new Base64().encodeToString(result); // 加密  
    //        } catch (Exception e) {  
    //        }  
    //        return null;  
    //    }  
        public static String encrypt(String data, String key) throws Exception {
            try {
    
                Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//"算法/模式/补码方式"NoPadding PkcsPadding
                int blockSize = cipher.getBlockSize();
    
                byte[] dataBytes = data.getBytes();
                int plaintextLength = dataBytes.length;
                if (plaintextLength % blockSize != 0) {
                    plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
                }
    
                byte[] plaintext = new byte[plaintextLength];
                System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
    
                SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
                IvParameterSpec ivspec = new IvParameterSpec(key.getBytes());
    
                cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
                byte[] encrypted = cipher.doFinal(plaintext);
    
                return new Base64().encodeToString(encrypted);
    
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }
    
        /** 
         * AES(256)解密 
         *  
         * @param content 
         *            待解密内容 
         * @param key 
         *            解密密钥 
         * @return 解密之后 
         * @throws Exception 
         */  
        public static String decrypt(String content, String key) {  
            try {  
      
                SecretKeySpec skey = new SecretKeySpec(key.getBytes(), algorithm);  
                IvParameterSpec iv = new IvParameterSpec(key.getBytes(), 0, offset);  
                Cipher cipher = Cipher.getInstance(transformation);  
                cipher.init(Cipher.DECRYPT_MODE, skey, iv);// 初始化  
                byte[] result = cipher.doFinal(new Base64().decode(content));  
                return new String(result); // 解密  
            } catch (Exception e) {  
            }  
            return null;  
        }  
      
        public static void main(String[] args) throws Exception {  
            String s = "65de2594-9ace-e211-915e-00155d607702";  
            // 加密  
            System.out.println("加密前:" + s);  
            String encryptResultStr = encrypt(s);  
            System.out.println("加密后:" + encryptResultStr);  
            // 解密  
            System.out.println("解密后:" + decrypt("CehzNznR6gQfgwahwUuoog=="));  
        }  
    }  

    3)方法调用直接参数main即可

    加密注意的点

    1、前后端相互校验,不同于单后端或前端加密。两端需要有共同的key配置。算法/模式/补码方式。

    2、后端java加密的算法/模式/补码方式配置是 AES/CBC/NoPadding,偏移量使用的是key。则前端vue中,也要使用相同的偏移,以及模式CBC,补码使用CryptoJS.pad.ZeroPadding。

    参考

    vue 方案https://chris-wei.github.io/2018/04/13/Crypto-js/

    java和vue使用AES加密验证前端请求 - qq_15070281的博客 - CSDN博客
    https://blog.csdn.net/qq_15070281/article/details/83652159

    展开全文
  • 用到了axios 和CryptoJS, 基本的安装啥的就不废话了 直接上封装的代码: import CryptoJS from 'crypto-js/crypto-js' import axios from 'axios';...// **************************** 加密代码 *******...

    用到了axios 和 CryptoJS, 基本的安装啥的就不废话了

    直接上封装的代码:

    import CryptoJS from 'crypto-js/crypto-js'
    import axios from 'axios';
    const CancelToken = axios.CancelToken
    // ****************************  加密代码 *******************************
    function DecryptData(data) {
    	try {
    		var sp = splitData(data);
    		if (!sp) return data;
    		var decrypt = CryptoJS.AES.decrypt(sp.data, CryptoJS.enc.Latin1.parse(sp.key), {
    			mode: CryptoJS.mode.ECB,
    			padding: CryptoJS.pad.Pkcs7
    		});
    		var tt = CryptoJS.enc.Utf8.stringify(decrypt).toString();
    		return JSON.parse(tt);
    	} catch (err) {
    		return data;
    	}
    }
    
    function splitData(str) {
    	var offset = parseInt(str.substr(3, 2));
    	var length = parseInt(str.substr(offset + 2, 2));
    	return {
    		key: str.substr(offset + 4, length),
    		data: str.substr(0, 3) + str.substr(5, offset - 3) + str.substr(offset + 4 + length)
    	}
    }
    
    function randomWord(randomFlag, min, max) {
    	var str = "",
    		range = min,
    		arr = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l',
    			'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
    			'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
    		];
    
    	// 随机产生
    	if (randomFlag) {
    		range = Math.round(Math.random() * (max - min)) + min;
    	}
    	var pos = 0;
    	for (var i = 0; i < range; i++) {
    		pos = Math.round(Math.random() * (arr.length - 1));
    		str += arr[pos];
    	}
    	return str;
    }
    
    function genKey() {
    	return randomWord(false, 16);
    }
    
    function EncryptData(data) {
    	var key = genKey();
    	var srcs = CryptoJS.enc.Utf8.parse(data);
    	var encrypted = CryptoJS.AES.encrypt(srcs, CryptoJS.enc.Latin1.parse(key), {
    		mode: CryptoJS.mode.ECB,
    		padding: CryptoJS.pad.Pkcs7
    	});
    	return combineEncrypt(key, encrypted.toString());
    }
    
    function randomoffset(length) {
    	return 16;
    }
    
    function combineEncrypt(key, encrypted) {
    	var offset = randomoffset(encrypted.length);
    
    	return encrypted.substr(0, 3) + offset +
    		encrypted.substr(3, offset - 3) + key.length + key +
    		encrypted.substr(offset);
    }
    
    function decryptInterceptorHandle(response) {
    	//解密
    	if (typeof(response.data) == "string") {
    		response.data = DecryptData(response.data);
    	}
    	return response;
    }
    
    function encryptInterceptorHandle(config) {
    	// 对所有POST put delete get请加密,必须是json数据提交,不支持表单
    	if (config && config.data) {
    		if (config.method == "post" || config.method == "put" || config.method == "delete" || config.method == "get") {
    			var encrypted = EncryptData(JSON.stringify(config.data))
    			config.data = encrypted;
    		}
    	}
    	return config;
    }
    // ****************************  加密代码 *******************************
    var cancel_ = false;
    export default {
    	install(Vue) {
    		let GLOBAL = Vue.prototype.GLOBAL;
    		GLOBAL.api = {
    
    		};
    		GLOBAL.ajax = {
    			requestInterceptors: [
    				(config) => {
    					if (GLOBAL.ajax.options.isDebug() && GLOBAL.ajax.options.Authorization)
    						config.headers.common["Authorization"] = GLOBAL.ajax.options.Authorization;
    					config.headers.common['Content-Type'] = 'application/json';
    					return config;
    				}
    			],
    			responseInterceptors: [],
    			responseErrorsInterceptors:[],
    			options: {
    				isDebug: () => {
    					return !(window.location.host.indexOf(GLOBAL.ajax.options.localKey ? GLOBAL.ajax.options.localKey : "localhost") ==
    						-1);
    				},
    			},
    			debug: {
    				enable: (options) => {
    					if (options.localKey)
    						GLOBAL.ajax.options.localKey = options.localKey;
    					if (options.Authorization)
    						GLOBAL.ajax.options.Authorization = options.Authorization;
    				}
    			},
    			encrypt: {
    				enable: (enable) => {
    					GLOBAL.ajax.options.encrypt = enable;
    				}
    			},
    			pushRequestInterceptors(it) {
    				//待校验,必须有参数
    				GLOBAL.ajax.requestInterceptors.push(it);
    			},
    			pushResponseInterceptors(it) {
    				//待校验,必须有参数
    				GLOBAL.ajax.responseInterceptors.push(it);
    			},
    			pushResponseErrorsInterceptors(it) {
    				//待校验,必须有参数
    				GLOBAL.ajax.responseErrorsInterceptors.push(it);
    			},
    			createApi(serviceName, baseURL) {
    				let apiName = "$" + serviceName;
    				if (GLOBAL.api[apiName]) {
    					return GLOBAL.api[apiName];
    				}
    
    				let tempService = axios.create({
    					baseURL: GLOBAL.ajax.options.isDebug() ? baseURL.dev : baseURL.prod
    				});
    				tempService.interceptors.response.use((res) => {
    					GLOBAL.ajax.responseInterceptors.forEach(it => {
    						res = it(res);
    					})
    					//解密方法;
    					if (!GLOBAL.ajax.options.encrypt) return res;
    					return decryptInterceptorHandle(res);
    				}, (error) => {
    					GLOBAL.ajax.responseErrorsInterceptors.forEach(it => {
    						error = it(error);
    					})
    
    					return error;
    				})
    				tempService.interceptors.request.use((config) => {
    					GLOBAL.ajax.requestInterceptors.forEach(it => {
    						config = it(config);
    					})
    					//加密方法;
    					if (!GLOBAL.ajax.options.encrypt) return config;
    					return encryptInterceptorHandle(config);
    				}, (error) => {
    					return error;
    				});
    				GLOBAL.api[apiName] = tempService;
    				return tempService;
    			},
    		}
    	}
    };
    

     

    展开全文
  • VUE 前端加密 PHP 后端解密 PHP 后端加密 VUE 前端解密 文章解析 AES AES 加密模式(CBC、ECB、CTR、OCF、CFB) ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一...


    VUE 前端加密 PHP 后端解密 PHP 后端加密 VUE 前端解密 教程



    文章解析


    AES

    AES 加密模式(ECB、CBC、CFB、CTR、CFB/OFB)

    在这里插入图片描述

    ECB:电码本模式(Electronic Codebook Book (ECB)
    这种模式是将整个明文分成若干段相同的小段,然后单独一个个加密,一个个输出组成密文。


    在这里插入图片描述

    CBC:密码分组链接模式(Cipher Block Chaining (CBC))
    这种模式是先将明文切分成若干小段,

    展开全文
  • VUE 1.引入cryptoJS npm install crypto-js --save-dev 或 cnpm install crypto-js --save-dev 2.编写工具类 import CryptoJS from 'crypto-js/crypto-js' // 默认的 KEY 与 iv 如果没有给 const KEY = CryptoJS....
  • vue 安装crypto.js cnpm install crypto-js --save ECB:是一种基础的加密方式,密文被分割成分组长度相等的块(不足补齐),然后单独一个个加密,一个个输出组成密文。 CBC:是一种循环模式,前一个分组的密文和...
  • 微服务和VUE(9): token验证-token后端生成以及前端获取 1. 前言 对于身份验证,传统来说,我们使用的是session。但是使用session会增加服务器的压力,并且不适合于今日的分布式集群开发。于是我们倾向于使用token。...
  • 基于.Net的MVC模拟登录,RSA非对称加密,web前端加密,C#后端解密。
  • 优化后端接口,前端使用axios实现接口功能 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-1.工具和本地环境 技能学习:学习使用php(tp6框架) + vue.js,开发前端全栈网站-2.启动项目 技能学习:...
  • SpringBoot+Vue博客系统---后端接口开发

    万次阅读 2021-01-13 10:30:02
    Java后端接口开发 从零开始搭建一个项目骨架,最好选择合适,熟悉的技术,并且在未来易拓展,适合微服务化体系等。所以一般以Springboot作为我们的框架基础,这是离不开的了。 然后数据层,我们常用的是Mybatis,易...
  • 为了满足360安全检测的要求,前端的密码不允许明文传输给后端进行密码验证,那么需要对密码进行前端加密后端解密,目前流行的做法是采用RSA前端用公钥加密后端用私钥解密的方案。 二、具体方案 (一)下载...
  • Vue.prototype.$jsEncrypt = JsEncrypt 注意(url和token的问题): 就是得出来的 String 是带 '+' 号的,但是这个加号在传给后台的时候实际是空格,前端生成的 token 是带 + 号生成的,但后台在生成 token 的...
  • 1 安装crypto-js npm install crypto-js 2 js端 import CryptoJS from 'crypto-js...后端也可以是使用EncryptUtil里面的encrypt对返回的数据加密前端再用上述js端里面的decrypt解密,从而达到前后端机密传输
  • 前端 VUE项目 AES加密 1. 明确 加密规则 加密方式方法:js-sha256, md5, crypto-js 下载依赖 npm install crypto-js npm install blueimp-md5 npm install js-sha256 引入依赖 import md5 from 'blueimp-md5' ...
  • 最近工作中,前端联调后端接口请求的数据是 JSON 格式的明文,考虑到安全问题,与后端同事沟通协调后,规定前端采用 3DES 对请求数据加密后端接收到请求后再用 3DES 进行解密。 二、效果图 三、具体实现 ...
  • MD5前端vue加密

    2019-10-07 01:52:34
    Vue 前端md5加密用户注册时将加密后的密码发送给后端存储当登陆的时候,再将加密后的密码和数据库中加密的密码相匹配。npm: https://www.npmjs.com/package/crypto-browserify此加密无须解密。安装: npm install ...
  • 我这里引用的是element UI框架,在这个里面的数据流动需要一下几个文件夹,也就是需要我们经常改动的地方。 下面以此介绍: ...他相当于桥梁,(在参数处)接收前端vue数据,(通过url)找到后端Con...
  • 文章目录前言一、依赖导入1、前端引入axios2、后端pom添加security依赖二、自定义WebSecurityConfigurerAdapter类1、创建SecurityConfig类继承WebSecurityConfigurerAdapter1.1允许跨域1.2自定义了用户登录校验和...
  • vue 前端jsencrypt公钥加密,python 后端私钥解密,实现密码加密传输参考:1.用python生成公钥和私钥2.vue代码安装jsencryptvue项目的main.js中加入如下代码在登录模块中加密用户密码3.python后端代码定义解密的函数...
  • 在请求前做配置 config => { if (getToken()) { config.headers['Authorization'] = getToken() // 让每个请求携带自定义token(加密token) 请根据实际情况自行修改 } config....
  • 初始node,用node进行数据库连接(mongodb)操作,node后端接口开发,返回前端请求响应 一:node是什么? 1、node.js是 一个js的运行环境,node是一个后端环境,搭载的是js语言 2、它可用于服务端开发,这样可以避免...
  • 1,安装插件 ...Vue.prototype.$jsEncrypt = JSEncrypt;//配置全局变量 3,在需要使用的组件(本文以登录页面对账号和密码进行了加密) getPublicKey({}).then((res)=>{//请求公钥接口 c
  • RSA加密 - Vue

    千次阅读 2021-07-05 14:09:55
    前端公钥加密 - 后端私钥解密 后端私钥加密 - 前端公钥解密 前端公钥加密-后端私钥解密 这种情况较为简单,是通用的做法 安装jsencrypt npm install jsencrypt RSAEncryption.js /** * 非对称加密-RSA * ...
  • 天猫精灵云云接入——前端VUE、服务器PHP、后端javaAliGenieVUE获取参数获取code跳转页面PHP通过获取code、grant_type换取token获取用户设备JAVA获取code获取token用户设备 第一次写博客,如果有什么问题或者疑问...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 4,650
精华内容 1,860
关键字:

后端接口加密前端vue

vue 订阅