移动时代的前端加密

移动时代的前端加密

标签: 加密 前端 HTML5 移动


背景

相比其它被编译成二进制的应用。前端这样的纯文本应用,太easy被解读和窜改。

前端为什么要加密?

加密重要的目的是出于对商业利益的保护。

  • 因为作品太easy被复制窜改。easy会失去渠道先机

窜改不限于下面:

  1. 署名被移除或替换;
  2. 链接地址被替换;
  3. 文案被改动;
  4. 广告被移除、替换或植入;

一些轻度游戏,用户仅仅会玩一两次,生命周期也就两三天。假设你开发的游戏被人山寨且他的渠道比你更广,那么对于流量就是致命打击。

  • HTML5 被山寨后太便宜

在淘宝上搜索「HTML5 微信小游戏」400套/10元

  • 避免泄露一些用于运营的脚本

參考:锤子手机天猫开卖遇乌龙事件

前端加密的目标

总之就是减少加密的成本添加破解的成本:假设每次花 1 分钟加密的应用,都须要花 2 小时以上去破解那就算成功了。

  • 加密后的文件不易过大;

100K 文件假设加密后到 1M 无疑添加了用户使用的成本和体验。

  • 没有人工介入不能破解;

即:破解的过程须要人工介入,人工成本无疑是最大的开销。

  • 限制在其它域名部署;

守护代码和业务放在一起。部署到其它域名则不能正常使用。

  • 不easy被调试跟踪;

对主流的调试工具有防范能力,如:Firebug、Chrome 开发人员工具。

哪些代码不须要加密?

  • 开源项目
  • 用于学习的项目

减少可读性的方法

压缩(compression)

压缩的目的一般是减少传输量,但也取到减少可读性的作用。

去掉凝视、多余的分隔符、空白字符、标识符简写。

这类工具有非常多:YUI CompressorUglifyJSGoogle Closure Compiler

「标识符简写」是一种压缩也是一种混淆。

混淆(obfuscation)

混淆常见的方法是分离静态资源、打乱控制流、添加无义的代码。

UglifyJSGoogle Closure Compiler 这类工具实际上也会做简单改变语句。

混淆是减少可读性的利器。有一款商业产品 jscrambler,最高配每一个月 95 美刀。

  • 标识符混淆

混淆前

function render(obj) {
  /* ... */
  console.log(obj.title);
}
render({title: ‘buy‘});

混淆后

function a(e){/* ... */console.log(e.title)}a({title:‘buy‘})
  • 逻辑混淆

混淆前

function render(obj) {
  /* ... */
  console.log(obj.title);
}
render({title: ‘buy‘});

混淆后

var self=this,o={};o.__defineSetter__(‘t‘,function(e){self[t(‘elosnoc‘)][t(‘gol‘)](e[t(‘eltit‘)])});function t(e){return e.split(‘‘).reverse().join(‘‘)};o[t(‘eltit‘)]=t(‘yub‘);o.t=o

混淆前

alert("Hello, JavaScript")

混淆后

?ω??= /`m′)? ~┻━┻   //*′?`*/ [‘_‘]; o=(???)  =_=3; c=(?Θ?) =(???)-(???); (?Д?) =(?Θ?)= (o^_^o)/ (o^_^o);(?Д?)={?Θ?: ‘_‘ ,?ω?? : ((?ω??==3) +‘_‘) [?Θ?] ,???? :(?ω??+ ‘_‘)[o^_^o -(?Θ?)] ,?Д??:((???==3) +‘_‘)[???] }; (?Д?) [?Θ?] =((?ω??==3) +‘_‘) [c^_^o];(?Д?) [‘c‘] = ((?Д?)+‘_‘) [ (???)+(???)-(?Θ?) ];(?Д?) [‘o‘] = ((?Д?)+‘_‘) [?Θ?];(?o?)=(?Д?) [‘c‘]+(?Д?) [‘o‘]+(?ω?? +‘_‘)[?Θ?]+ ((?ω??==3) +‘_‘) [???] + ((?Д?) +‘_‘) [(???)+(???)]+ ((???==3) +‘_‘) [?Θ?]+((???==3) +‘_‘) [(???) - (?Θ?)]+(?Д?) [‘c‘]+((?Д?)+‘_‘) [(???)+(???)]+ (?Д?) [‘o‘]+((???==3) +‘_‘) [?Θ?];(?Д?) [‘_‘] =(o^_^o) [?o?] [?o?];(?ε?)=((???==3) +‘_‘) [?Θ?]+ (?Д?) .?Д??+((?Д?)+‘_‘) [(???) + (???)]+((???==3) +‘_‘) [o^_^o -?Θ?]+((???==3) +‘_‘) [?Θ?]+ (?ω?? +‘_‘) [?Θ?]; (???)+=(?Θ?); (?Д?)[?ε?]=‘\\‘; (?Д?).?Θ??=(?Д?+ ???)[o^_^o -(?Θ?)];(o???o)=(?ω?? +‘_‘)[c^_^o];(?Д?) [?o?]=‘\"‘;(?Д?) [‘_‘] ( (?Д?) [‘_‘] (?ε?+(?Д?)[?o?]+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ (???)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((???) + (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ (???)+ (?Д?)[?ε?]+((???) + (?Θ?))+ (c^_^o)+ (?Д?)[?ε?]+(???)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ (?Θ?)+ (c^_^o)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ ((???) + (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ (???)+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ (???)+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ ((???) + (o^_^o))+ (?Д?)[?ε?]+((???) + (?Θ?))+ (???)+ (?Д?)[?ε?]+(???)+ (c^_^o)+ (?Д?)[?ε?]+(?Θ?)+ (?Θ?)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ ((o^_^o) +(o^_^o))+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) - (?Θ?))+ (o^_^o)+ (?Д?)[?ε?]+(?Θ?)+ (???)+ (o^_^o)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+(?Θ?)+ ((???) + (?Θ?))+ (?Θ?)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ (c^_^o)+ (?Д?)[?ε?]+(?Θ?)+ ((o^_^o) +(o^_^o))+ (???)+ (?Д?)[?ε?]+(???)+ ((o^_^o) - (?Θ?))+ (?Д?)[?ε?]+((???) + (?Θ?))+ (?Θ?)+ (?Д?)[?o?]) (?Θ?)) (‘_‘);

混淆前

alert("Hello, JavaScript")

混淆后

$=~[];$={___:++$,$$$$:(![]+"")[$],__$:++$,$_$_:(![]+"")[$],_$_:++$,$_$$:({}+"")[$],$$_$:($[$]+"")[$],_$$:++$,$$$_:(!""+"")[$],$__:++$,$_$:++$,$$__:({}+"")[$],$$_:++$,$$$:++$,$___:++$,$__$:++$};$.$_=($.$_=$+"")[$.$_$]+($._$=$.$_[$.__$])+($.$$=($.$+"")[$.__$])+((!$)+"")[$._$$]+($.__=$.$_[$.$$_])+($.$=(!""+"")[$.__$])+($._=(!""+"")[$._$_])+$.$_[$.$_$]+$.__+$._$+$.$;$.$$=$.$+(!""+"")[$._$$]+$.__+$._+$.$+$.$$;$.$=($.___)[$.$_][$.$_];$.$($.$($.$$+"\""+$.$_$_+(![]+"")[$._$_]+$.$$$_+"\\"+$.__$+$.$$_+$._$_+$.__+"(\\\"\\"+$.__$+$.__$+$.___+$.$$$_+(![]+"")[$._$_]+(![]+"")[$._$_]+$._$+",\\"+$.$__+$.___+"\\"+$.__$+$.__$+$._$_+$.$_$_+"\\"+$.__$+$.$$_+$.$$_+$.$_$_+"\\"+$.__$+$._$_+$._$$+$.$$__+"\\"+$.__$+$.$$_+$._$_+"\\"+$.__$+$.$_$+$.__$+"\\"+$.__$+$.$$_+$.___+$.__+"\\\"\\"+$.$__+$.___+")"+"\"")())();

加密(encryption)

这里「加密」指代码内容可逆编码。而文中「前端加密」指页面和相关资源文件处理后能正常运行。

  • 简单 base64

加密前

function a(e){/* ... */console.log(e.title)}a({title:‘buy‘})

加密后

eval(atob("ZnVuY3Rpb24gYShlKXsvKiAuLi4gKi9jb25zb2xlLmxvZyhlLnRpdGxlKX1hKHt0aXRsZTonYnV5J30p"));
  • Packer

加密前

function a(e){/* ... */console.log(e.title)}a({title:‘buy‘})

加密后

eval(function(p,a,c,k,e,r){e=String;if(!‘‘.replace(/^/,String)){while(c--)r[c]=k[c]||c;k=[function(e){return r[e]}];e=function(){return‘\\w+‘};c=1};while(c--)if(k[c])p=p.replace(new RegExp(‘\\b‘+e(c)+‘\\b‘,‘g‘),k[c]);return p}(‘3 0(1){4.5(1.2)}0({2:\‘6\‘})‘,7,7,‘a|e|title|function|console|log|buy‘.split(‘|‘),0,{}))

新技术带来的新思路

到移动时代我们能够放心的用上 HTML5、CSS3,使用一些新特性结合已有的方案,能够更大程度添加破解的成本。

代码能够放置其它位置

将代码放到非 JS 文件里,添加代码定位的难度。

  • 放到 png 中

利用 HTML Canvas 2D Context 获取二进制数据的特性。能够用图片来存储脚本资源。

  • 放到 css 文件里

利用 content 样式能存放字符串的特性,相同能够用来存储脚本资源。

运行代码字符串

不管代码放到哪。都须要运行。运行代码字符串的方式有例如以下几种:

  • 创建 <script> 运行
var script = document.createElement(‘script‘);
script.src = ‘data:application/javascript,console.log("Hello%20world!"))‘;
document.querySelector(‘script‘).parentNode.appendChild(script);
  • 调用 setTimeout() / setInterval() 运行
setTimeout(‘console.log("Hello world!")‘, 0);
  • 创建 new Function() 运行
new Function(‘console.log("Hello world!")‘)();
  • 使用 Worker 运行
var URL = window.URL || window.webkitURL;
var Blob = window.Blob || window.webkitBlob;
var blobURL = URL.createObjectURL(
    new Blob([‘console.log("Hello World!")‘], {type: ‘application/javascript‘})
);
new Worker(blobURL);
URL.revokeObjectURL(blobURL);
  • 使用 DOM 事件运行
var div = document.createElement(‘div‘);
div.innerHTML = "<img src=! onerror=\"console.log(‘Hello world!‘)\">";
  • location 赋值 javascript 协议的链接
location = ‘javascript:console.log("Hello world!");‘;

怎样防止代码运行被截获

比想象的难太多

  • 截获 eval() / new Function() 的演示样例代码
eval = function() {
  console.log(‘eval‘, JSON.stringify(arguments));
};

eval(‘console.log("Hello world!")‘);

Function = function() {
  console.log(‘Function‘, JSON.stringify(arguments));
  return function() {};
};

new Function(‘console.log("Hello world!")‘)();
  • 还以为用字面量就妥妥了。o(╯□╰)o 后来发现是杯具的
(function(){}).constructor(‘console.log("Hello world!")‘)()
  • 截获 constructor 的演示样例代码
Function.prototype.__defineGetter__(‘constructor‘, function () {
    return function () {
        console.log(‘constructor‘, JSON.stringify(arguments));
    };
});
(function() {}).constructor(‘console.log("Hello world!")‘);
  • 眼下能想到的是推断 eval 是否被重定向

演示样例,假设 eval 被重定向 z 变量不会被泄露

(function(x){
    var z = ‘console.log("Hello world!")‘;
    eval(‘function x(){eval(z)}‘);
    x();
})(function() { /* ... */ });

防止开发人员工具

再复杂的前端加密也难对付调试工具的跟踪分析。

while(1){} // 卡死

混合加密

单个方法总是easy被破解。但组合起来千变万化就不那么easy了!破解成本显然指数增长。

  • 嵌套加密
「C 方法加密
  「A 方法加密
   ...
   」
   ...
  「B 方法加密
   ...
   」
 」
  • 随机加密
「随机方法加密
  「随机方法加密
   ...
   」
   ...
  「随机方法加密
   ...
   」
 」

实际案例

这里要安利两下:

  • 我和小伙伴们开发的剪纸游戏 天天爱剪纸,用到了混合加密,你能够尝试破解挑战一下。

    (已被 @前端农民工 扒了)

  • 独立开发的代码预处理工具 jdists。非常适合用来做混合加密。

參考:jdists 混合加密演示样例

更有力的防范

非常难做到 100% 防止逆向project,仅仅是添加一些破解的成本。

使用专属素材

改动素材也就是要做同一套素材,这个事实上不比改动代码easy到哪去。

不是单一的前端应用,依赖服务端的存储

前端easy破解。后端却不easy。物理上就隔离了。

更好的产品和服务,更快的迭代

再怎么山寨也山寨不了精髓。

參考资料

时间: 2024-10-27 07:00:21

移动时代的前端加密的相关文章

JAVA WEB实现前端加密后台解密

最近在研究登陆密码的加密,下边上具体代码,只是给出核心代码,具体的代码视业务而定吧,给位有什么问题或者意见请留言. 加密方法用的是AES-128-CBC,BASE64用的是org.apache.commons.codec.binary.Base64 JS代码: var password = "1234567890,./"; var key = CryptoJS.enc.Utf8.parse("0102030405060708");//密钥,128位加密密钥为16位

前端加密

什么是前端加密?前端加密就是在客户端对用户要提交的内容进行加密,从而降低服务器端的压力,使用前端加密的好处不仅仅是性能方面的,更多的也是安全方面的,例如我们使用前端加密对密码进行多次加密,那么每一次都会消耗很大的性能,如果是破解密码的话,那就需要不断的消耗大量的客户端的资源,从而达到延长破解密码的时间,得到很高的安全性. 怎么实现前端加密?这里我们需要借助js实现的MD5加密框架,直接在客户端使用就可以了,具体实现可参考:http://pajhome.org.uk/crypt/md5/

jsdetox反混淆js内容,解密前端加密参数

https://github.com/svent/jsdetox 这个是一个比较好的反混淆,针对前端加密还是可以调试的 就是安装比较傻逼,需要bundler1.0左右,老子安装了半天没安装上,我曹你吗的 ruby gem 这个垃圾社区  操你吗! 真的是找骂 一个地址换2次... 资料这找不到 那 找不到 针对有人无法安装jsdetox的话 就用这个 https://zeltser.com/docker-application-distribution/ 看下docker ,官方的仓库是有镜像的

《转载分享》互联网+”时代,爱加密卫道移动应用安全

移动互联网应用市场的高度繁荣宣告着“互联网+”时代的到来,传统行业商家.企业都开始转型互联网:汽车.服装.零食也开始提供买卖一体化的APP服务……越来越多传统行业开始向互联网紧密结合. “互联网+”让传统行业萌发第二春,带来新一轮机遇和挑战.传统行业与互联网之间的紧密联系,当属机遇和挑战并存的手游.移动金融领域最为火热.2014年手游市场被行业人士称为“IP元年”,金融类的众筹.p2p.第三方支付等也纷纷呈现强劲的发展姿态. “互联网+”背后,移动应用安全状况频发 伴随着“互联网+”的兴起,传统

Retina时代的前端视觉优化

随着New iPad的发布,平板也将逐渐进入Retina时代,在高分辨率设备里图片的显示效果通常不尽人意,为了达到最佳的显示效果就需要对图片进行优化,这里介绍一些优化方法: 一.用CSS替代图片 这一点在任何时候都适用:只是在当前我们可以更多的使用样式表来制作出设计效果,CSS3的圆角.渐变.模盒阴影.字体阴影能帮助我们处理绝大多数视觉效果,并且在各种分辨率下都有良好的表现. CSS Button 二.为高分辨率设备提供高清图片 如果必须使用图片,通常是准备2套图片,一套原始尺寸( 为普通设备准

jsencrypt参数前端加密c#解密

写程序时一般是通过form表单或者ajax方式将参数提交到服务器进行验证,如何防止提交的请求不被抓包后串改,虽然无法说绝对安全却给非法提交提高了难度,本篇采用jsencypt在前端进行加密的并且用C#在后端解密,在投票提交分数等H5应用上可以使用的上,并且进行简单的封装. 1.demo <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-eq

rsa加密算法及js的JSEncrypt实现前端加密

最近的项目中用到了rsa加密算法,在实现了相关功能之后,我去了解了一下rsa相关原理,于是就写了这篇博客啦. 首先介绍一下什么是rsa加密算法: 作为非对称加密算法的老大,rsa号称是地球上最安全的加密算法. 首先了解一些数学背景(我发现我真的好喜欢看数学概念0.0),这里就不再赘诉相关数学背景了,但是请务必要理解这些概念,贴一个我觉着讲得特别清晰的概念,便于理解: https://blog.csdn.net/u014044812/article/details/80782448 然后介绍一下r

RSA前端加密解密

<html> <head> <title>JavaScript RSA Encryption</title> <meta charset="UTF-8"> <script src="js/jquery-1.11.3.min.js"></script> <script src="js/jsencrypt.min.js"></script> &

前端加密传输 crypto-js AES 加密和解密

配置: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0&q