IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> cocos2d-js 手游解密jsc和WebSocket数据aes加密解密分析② -> 正文阅读

[网络协议]cocos2d-js 手游解密jsc和WebSocket数据aes加密解密分析②

前面的http授权成功后,用的是WebSocket进行登录

Fiddler 抓包显示

双击进入插件详情,发现是加密的,那就进入js源码看看

?

js源码看看

搜索bufferToData后,得到关键代码

e.prototype.initWithBuffer = function(t) {
switch (this.state) {
case e.ENetDataState.empty:
var n = this.bufferToData(t);
if (null == n) this.state = e.ENetDataState.broken; else {
this.data = n;
this.buffer = t;
this.state = e.ENetDataState.normal;
}
break;

case e.ENetDataState.normal:
cc.error(r, "initWithBuffer", " can not init NetData, the state is normal");
break;

case e.ENetDataState.broken:
cc.error(r, "initWithBuffer", " can not init NetData, the state is broken");
}
};

具体实现,主要是看bufferToData 和?dataToBuffer

t.prototype.bufferToData = function(e) {
var o = {
head: null,
content: null
}, n = a.BYProto.sizeof(r.default.Head), c = e.subarray(0, n);
o.head = a.BYProto.interpret(c, r.default.Head);
var l = e.subarray(n, e.byteLength), u = l;
if (o.head.cbDataKind == t.EncryptFlag && l && l.byteLength > 0) {
if (!((u = i.CryptoTool.aesDecryptBuffer(this.aesKey, this.aesIV, l)).byteLength + n >= o.head.wTrimSize)) {
cc.error(s, "bufferToData", "解密后长度不匹配,wMainCmdID = " + o.head.wMainCmdID + ", wSubCmdID = " + o.head.wSubCmdID + ", decrypt.byteLength = " + u.byteLength, ", wTrimSize = " + o.head.wTrimSize);
return;
}
u = u.subarray(0, o.head.wTrimSize - n);
}
o.content = u;
return o;
};
t.prototype.dataToBuffer = function(e) {
var o = a.BYProto.sizeof(r.default.Head), n = e.content;
e.head.cbDataKind = t.EncryptFlag;
if (n) {
e.head.wTrimSize = o + n.byteLength;
var s = i.CryptoTool.aesEncryptBuffer(this.aesKey, this.aesIV, n);
e.head.wPacketSize = o + s.byteLength;
var c = a.BYProto.construct(e.head);
return a.BYProto.concatenateBuffer(c, s);
}
e.head.wTrimSize = o;
e.head.wPacketSize = o;
return a.BYProto.construct(e.head);
};

?解密关键

i.CryptoTool.aesDecryptBuffer(this.aesKey, this.aesIV, l)

找找?aesKey 和?aesIV 是怎么生成

搜索得到?setAes 方法赋值了密钥 和 向量

t.prototype.setAes = function(e, t) {
this.aesKey = e;
this.aesIV = t;
};

再一波寻找,终于在send 方法找到?setAes 的调用

c.setAes(this.aesKeyBuffer, this.aesIvBuffer);

e.prototype.send = function(e, t, o) {
if (!cc.game.isPaused() && this.state != n.broken) {
var r = new s.default.Head();
r.wMainCmdID = e;
r.wSubCmdID = t;
var i = {
head: r,
content: o
}, c = new a.NetDataWithBY();
if (!this.aesKeyBuffer) {
this.aesKeyBuffer = u.CryptoTool.randomAesKeyBuffer();
this.aesIvBuffer = u.CryptoTool.randomAesIvBuffer();
}
c.setAes(this.aesKeyBuffer, this.aesIvBuffer);//setAes 的调用
c.initWithData(i);
c.getState() == s.default.ENetDataState.normal ? c.isPingMsg() ? this.unshiftSendArray(c) : c.isKernelDetectSocketMsg() ? this.unshiftSendArray(c) : n.reconnecting == this.state ? this.backupArraySend.push(c) : this.sendArray.push(c) : cc.error(h, this.cachekey, "send", "send fail, the NetData state is not normal");
}
};

?我们要找的aesKey 和?aesIV, 是由 aesKeyBuffer和 aesIvBuffer 赋值。

分析可以得知,aesKey和aesIV都是每次启动随机生成的。

if (!this.aesKeyBuffer) {??//这里判断密钥是否创建
    //创建随机密钥 和 向量
    this.aesKeyBuffer = u.CryptoTool.randomAesKeyBuffer();
    this.aesIvBuffer = u.CryptoTool.randomAesIvBuffer();
}


//取Key
e.randomAesKeyBuffer = function() {
    return n(16);
};
//取Iv
e.randomAesIvBuffer = function() {
    return n(16);
};

//生成随机
function n(e) {
    for (var t = [], o = 0; o < e; o++){ 
        t.push(Math.floor(255 * Math.random() + 1));
    }
    return new Uint8Array(t);
}

那么我们就测试一下,把重要数据写到本地验证一下。

//js 写文件到本地方法
var writablePath = jsb.fileUtils.getWritablePath();
writablePath += "xdd/";
var fileName = "bufferToData" + "_file.js";
var fullPath = writablePath + fileName;
jsb.fileUtils.createDirectory(writablePath);
jsb.fileUtils.writeStringToFile(JSON.stringify("我的内容"), fullPath);

?修改js代码保存->加密->放回缓存位置,打开游戏(具体方法请看上集)

?

?

打开手机xdd目录,得到想要的数据,

?

?

?数据有些看不懂,解析一下在看看【字节集】还原到【十六进制】

还原过程

?得到 纯字节集{8,0,41,0,42,0,1,0,14,0,2,154,1,92,44,65,229,89,133,72,51,37,57,59,138,208,216,174,148,209,13,209,53,218,63,108,35,100,39,4,124,111}

?字节集_字节集到十六进制 (zj)

得到?十六进制080029002A0001000E00029A015C2C41E55985483325393B8AD0D8AE94D10DD135DA3F6C236427047C6F

开始验证解密(密钥也写到了本地,重复上面转换成16进制)

?

aesKey = 127F763C0FEC0D5EEA997C66BA44B2CC

aesIV? =? ?9A1AB62788FC8F89B320425595292AEB?

?经过测试,前20位是包头,需要删除掉再解密

原?

?080029002A0001000E00029A015C2C41E55985483325393B8AD0D8AE94D10DD135DA3F6C236427047C6F

?删掉前20位后

029A015C2C41E55985483325393B8AD0D8AE94D10DD135DA3F6C236427047C6F

解密结果,这里前面显示乱码,是因为?Google?protobuff?格式原因

我们把解密内容设置为十六进制显示

-------->返回类型:文本型
-->系统计算耗时:2 ms
-->系统计算结果:0801121be5beaee4bfa1e68e88e69d83e9aa8ce8af81e5a4b1e8b4a5efbc81


放入protobuff 解析工具,解析一下,原来如此。

?


返回信息是解密完成。

但是发送数据没有解密成功,有时间可以一起研究研究

多次分析,发现也是也是去掉前20位,

?0800B701BA0101000700B1A9DAE51C77BF7C53FE29DA01193AC0972E6AB5BBDCA5DD9A05F606AB236DC2EC384837A0AC8D816B41141D78778C07296A652155FEE87BA1340E9A849561B4F4D6298E86EA96B25E6E445F704606910629C9DD0795869D87B785F914336C896A276981A85F5FC9D93D9064868D7F9D723DA50890B150F4B25838D7BCA7D8972F7C6D50BF64C5C6204076A41ED4618BC8014D6AB4E52B04B3560B6355F3B9776309368F04FA3E6AD3059C93245A87BBFA47A277F62641FFD8E7997085D15F1802590076F326688A3421435F41547BD2D127813F7FC29219B213B4178E59E26DA0A4AD2471830F9B26A55D94D565659AAB3A6060BA46CAB69FFCDF373CF3C32C24AD04442E589C8C48555866127AD6C61939AD119A40BF995E86B1607123FAD7E8521A5F4B16ABE71242EC635A2436404DD1BE74EDA5C3583A5D321A37298DCD64C00F2D81813303C7383D8B195BA0F5EB9A34409E90D4F3CCF5D520FD0CE26FA8780C4FB33E6748A9FEA638E10F4C17AF39F1AD2C229D010FDAD21FDF1F76E2BC1634D4CF255B62619667E8601E63EB45F25CA44721C47FB80024107C358F3D63678B9A52D731293849F3A09F75A1EA

B1A9DAE51C77BF7C53FE29DA01193AC0972E6AB5BBDCA5DD9A05F606AB236DC2EC384837A0AC8D816B41141D78778C07296A652155FEE87BA1340E9A849561B4F4D6298E86EA96B25E6E445F704606910629C9DD0795869D87B785F914336C896A276981A85F5FC9D93D9064868D7F9D723DA50890B150F4B25838D7BCA7D8972F7C6D50BF64C5C6204076A41ED4618BC8014D6AB4E52B04B3560B6355F3B9776309368F04FA3E6AD3059C93245A87BBFA47A277F62641FFD8E7997085D15F1802590076F326688A3421435F41547BD2D127813F7FC29219B213B4178E59E26DA0A4AD2471830F9B26A55D94D565659AAB3A6060BA46CAB69FFCDF373CF3C32C24AD04442E589C8C48555866127AD6C61939AD119A40BF995E86B1607123FAD7E8521A5F4B16ABE71242EC635A2436404DD1BE74EDA5C3583A5D321A37298DCD64C00F2D81813303C7383D8B195BA0F5EB9A34409E90D4F3CCF5D520FD0CE26FA8780C4FB33E6748A9FEA638E10F4C17AF39F1AD2C229D010FDAD21FDF1F76E2BC1634D4CF255B62619667E8601E63EB45F25CA44721C47FB80024107C358F3D63678B9A52D731293849F3A09F75A1EA

?

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2022-01-01 14:20:18  更:2022-01-01 14:20:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 12:30:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码