前端代码加密
公开数据,无意义?
前端一切都是公开的,代码加密对于企业级项目确实没有意义,对许多个人开发者,简单的代码加密能有效的防止代码在未经授权时被滥用,也起到了筛选的作用
代码保护
代码压缩,变量、属性替换,删除注释
对抗:通常用一些脚本美化,代码就基本还原了
增加无意义代码
影响自己的页面性能和维护
脚本加壳
eval (…………………………..…………….
……………. !@#$%^&* …………….
.…………………………..……………. )
对抗:eval 换成 alert 就能原形毕露
加壳欺骗
eval log ( ……………………………………………………
T = setTimeout(bomb, 0) // 埋一颗定时炸弹
code += 'clearTimeout(T)' // 执行 eval 可解除
……………………………………………………………………)
AST抽象语法树混淆
数据加密(数据脱敏)
通常前端做数据加密是没有意义的,因为 https(ssl/tls),socket(ssl)保证了端到端的传输安全。但是在一些场景加密是有一定作用的。
大家在用公司网络的时候,如果服务器代理模式是中间人模式(先要在用户本地安装服务器的根证书,用户先发https请求给代理服务器,代理服务器再转发请求给目标服务器;还有一种模式,就是用户直接发请求给目标服务器,代理服务器仅代理流量,这种模式代理服务器仅能看到浏览哪些页面,看不到具体信息),后台是以明文显示数据的,如果能在前端简单做下加密,也能有效保护用户的信息;还有一种情况,许多用户在很多网站密码都是一样的,如果有一个网站数据被截获或者泄露,通常用户其他网站的数据就有安全风险,另外浏览器的插件也能捕获到用户的请求。
对称加密
对称加密算法,又称为共享密钥加密算法。在对称加密算法中,使用的密钥只有一个,发送和接收双方都使用这个密钥对数据进行加密和解密。
其优点是算法公开、计算量小、加密速度快、加密效率高;缺点是密钥泄露之后,数据就会被破解。一般不推荐单独使用。
常见的算法:AES、ChaCha20、3DES
非对称加密
非对称加密算法,又称为公开密钥加密算法。它需要两个密钥,一个称为公开密钥 (public key),即公钥;另一个称为私有密钥 (private key),即私钥。
他俩是配对生成的,就像保险柜和钥匙的关系,客户端将数据通过公钥进行加密(东西放入保险柜),服务端通过私钥解密获得数据(钥匙打开保险柜)
因为加密和解密使用的是两个不同的密钥,所以这种算法称为非对称加密算法。其优点是算法强度复杂、安全性高;缺点是加解密速度没有对称加密算法快。
常见的算法:RSA 、Elgamal
散列/哈希算法
散列算法又称散列函数、哈希函数,是把消息或数据压缩成摘要,使得数据量变小,将数据的格式固定成特定长度的值。计算出一段不可逆向计算的数据(数据移位,删除,丢失了部分数据),用于校验数据的完整性。
通常远端服务器存储计算后的数值,与前端经加密数据对比,若不同,则被篡改
常见的算法:MD4、MD5、SHA
前端简单加密实现
AES 加密
base64 编码
var str = 'RUNOOB'
var enc = window.btoa(str) //编码成base64的
var dec = window.atob(enc) //把base64解码
var res = '编码字符串为: ' + enc + '<br>' + '解码后字符串为: ' + dec
console.log(res)
当遇到中文时,需要先对中文转码否则会乱码。
var str = btoa(encodeURIComponent("中文汉字"));
//还可以解码回来
decodeURIComponent(atob(enc)) => 中文汉字
md5 校验数据
<script src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js"></script>
<script>
var b =$("#logPassword");
$.md5(b.val())
<script>
//加盐值
console.log(md5(md5("test") + "a"));
sha 校验数据
<script type="text/ecmascript" src="sha1.js"></script>
var sha = hex_sha1('mima123465');
console.log(sha);
RSA 加密
<script src="js/jsencrypt.js"></script>
获得后端的公钥
var publicKey = null;
$.ajax({
url: "xxx",
type: "post",
dataType: "text",
success: function(data) {
var encrypt = new JSEncrypt();
if(data){
publicKey = data;
};
}
});
通过公钥对用户名和密码加密
encrypt.setPublicKey(publicKey);
var username;
var password;
username = encrypt.encrypt(vm.username.trim());
password = encrypt.encrypt(vm.password.trim());
加密后的用户名密码请求后台
$.ajax({
type: "POST",
url: "xxxxxx",
data: {
"username":username,
"password":password,
},
dataType: "json",
success: function (result) {
if (result.code == 0) {//登录成功
parent.location.href = 'index.html';
} else {
vm.error = true;
vm.errorMsg = result.msg;
vm.refreshCode();
}
}
});