目标
1:禁止网站分析。
2:保证Cookies安全。
3:http请求数据安全。
4:http请求防重。
方案
1:禁止网站分析
- 禁止右键审查元素和开启F12
使用disable-devtool库:https://github.com/theajack/disable-devtool
- 如果开启了F12,那么出发debug干扰审查元素
// 循环监测,当检测到开启了Dev那么开启deg模式
setInterval(function () {
check();
}, 4000);
var check = function () {
function doCheck(a) {
if (("" + a / a)["length"] !== 1 || a % 20 === 0) {
(function () { }["constructor"]("debugger")());
} else {
(function () { }["constructor"]("debugger")());
}
doCheck(++a);
}
try {
doCheck(0);
} catch (err) { }
};
check();
2:保证Cookies安全
- 使用AES将保存的内容加密:基于crypto-js
import CryptoJS from "crypto-js";
const keyCode = "223434ae2f1123a234cb"
export default {
en(word, keyStr = keyCode) {
let enc = CryptoJS.AES.encrypt(word, CryptoJS.enc.Hex.parse(keyStr), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return enc.ciphertext.toString()
},
de(word, keyStr = keyCode) {
let dec = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(word), CryptoJS.enc.Hex.parse(keyStr), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return CryptoJS.enc.Utf8.stringify(dec)
}
};
3:http请求数据安全。
- 将请求体加密,密钥要和服务器端匹配
import CryptoJS from "crypto-js";
const keyCode = "223434ae2f1123a234cb"
export default {
en(word, keyStr = keyCode) {
let enc = CryptoJS.AES.encrypt(word, CryptoJS.enc.Hex.parse(keyStr), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return enc.ciphertext.toString()
},
de(word, keyStr = keyCode) {
let dec = CryptoJS.AES.decrypt(CryptoJS.format.Hex.parse(word), CryptoJS.enc.Hex.parse(keyStr), {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return CryptoJS.enc.Utf8.stringify(dec)
}
};
- 在拦截器中统一加密
// request interceptor
service.interceptors.request.use(
config => {
config.data = encry.en(JSON.stringify(config.data))
return config
},
error => {
Promise.reject(error)
}
)
- java后台对应加密
package com.cloudcc.microservice.devconsolesvc.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StringUtils;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@Slf4j
public class AESUtil {
/**
* 加密算法:AES
*/
private static String Algorithm = "AES";
/**
* 算法/模式/补码方式
*/
private static String AlgorithmProvider = "AES/ECB/PKCS5Padding";
/**
* 默认密钥:
*/
private static String defaultKey = "devconsole-svc12";
/**
* @param src 明文
* @param key 密钥
* @return
* @version 1.0
* @description 加密
* @date 2021/7/26 19:52
*/
public static String encrypt(String src, String key) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
if (StringUtils.isEmpty(key)) {
key = defaultKey;
}
SecretKey secretKey = new SecretKeySpec(key.getBytes("utf-8"), Algorithm);
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] cipherBytes = cipher.doFinal(src.getBytes(Charset.forName("utf-8")));
return byteToHexString(cipherBytes);
}
/**
* @param src 密文
* @param key 密钥
* @return
* @version 1.0
* @description 解密
* @date 2021/7/26 19:57
*/
public static String decrypt(String src, String key) throws Exception {
if (StringUtils.isEmpty(key)) {
key = defaultKey;
}
SecretKey secretKey = new SecretKeySpec(key.getBytes("utf-8"), Algorithm);
Cipher cipher = Cipher.getInstance(AlgorithmProvider);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] hexBytes = hexStringToBytes(src);
byte[] plainBytes = cipher.doFinal(hexBytes);
return new String(plainBytes, "utf-8");
}
/**
* 将byte转换为16进制字符串
*
* @param src
* @return
*/
public static String byteToHexString(byte[] src) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < src.length; i++) {
int v = src[i] & 0xff;
String hv = Integer.toHexString(v);
if (hv.length() < 2) {
sb.append("0");
}
sb.append(hv);
}
return sb.toString();
}
/**
* 将16进制字符串装换为byte数组
*
* @param hexString
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] b = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
b[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return b;
}
private static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
public static void main(String[] args) {
try {
// java中密钥必须是16的倍数
String key = "comconsbck-moc21";
String src = "{\n" +
" \"head\":{},\n" +
" \"body\":{\n" +
" \n" +
" \"pageApi\":\"test-a\"\n" +
" }\n" +
"}";
System.out.println("vue中的密钥:" + byteToHexString(key.getBytes()));
System.out.println("原字符串:" + src);
String enc = encrypt(src, key);
System.out.println("加密:" + enc);
System.out.println("解密:" + decrypt("de1132750d63a572333933c9b5ed545f", key));
} catch (Exception e) {
e.printStackTrace();
}
}
}
4:http请求防重。
- 请求体中添加时间戳,服务器端获取和服务器事件对比,时间差小于5分钟,为有效请求。
- 请求体中添加随机字符串,服务器将随机字符串放入Map中,如果请求的随机串存在Map中,那么视为无效请求。
网友评论