前言

根据网上的众多分析来看,很多QQTEA算法要么是反编译分析的,要么是根据其他版本改写的,很少有直接根据源码分析改写的,而且很多分析体现在源码里,梳理性的内容不多。后面的人去看又要重新梳理。

一、寻找函数

这里根据腾讯公开的JS文件分析,比反编译简单一些,至少能直接看到源码,JS文件:c_login_2.js

首先,看到这个JS很多人可能无从下手,首先要做的就是下载下来然后格式化

需要注意的是,网上大多数在线格式化网站不能正确的处理自执行函数,建议使用eclipse或者webstorm

eclipse格式化之后,有5639行,那么怎么才能找到TEA算法所在函数呢,搜索即可,不过我已经找好了

在notepad++下,Alt+0折叠所有,找到带一个参数的自执行函数,展开就可以了,注意:这个js文件一共有两个自执行函数,找不准的搜索关键字tea吧

找到之后,我们把这个函数单独拷贝出来调试,具体内容这里就不贴了,太长了

二、调用函数

接下来我们来看一下这个函数的加密解密效果,可能有人不知道怎么调,这里介绍两种方法

F12控制台法:Chrome或者Firefox打开一个空页面,复制这个函数,直接粘贴到控制台,回车,

然后复制如下语句

TEA.initkey("111");
var jiamihou = TEA.encrypt("8888999911112222");
console.log(jiamihou);
var jiemihou = TEA.decrypt(jiamihou);
console.log(jiemihou);

效果如下

JS文件法:新建一个js文件如tea.js,复制前面那个函数,然后在函数结束的分号后面再加一段

TEA.initkey("111");
var jiamihou = TEA.encrypt("8888999911112222");
alert(jiamihou);
var jiemihou = TEA.decrypt(jiamihou);
alert(jiemihou);

之后新建一个空白的html页面,在页面的,head>标签里面引用这个js

<script src="qqtea.js"></script>  

之后用浏览器打开这个页面就能看到两个弹窗效果了。

三、分析函数(加密篇)

上面只是演示这个函数的效果,下面才是重头戏,分析这个js的加密解密过程

加密方法:

encrypt: function (E, D) {  var C = q(E, D);  var B = j(C);  return y(B)  }, 

其中q(E, D)方法是转码用的,方法如下

 //转码,如果E参数存在,直接转ascii码存入数组,如果不存在,每两位当做16进制转ASCII码//D数组的长度取决于传入F的长度function q(F, E) {  var D = [  ];  if (E) {  for (var C = 0; C < F.length; C++) {  D[C] = F.charCodeAt(C) & 255  //取ASCII码,只取8位}  } else {  var B = 0;  for (var C = 0; C < F.length; C += 2) {  D[B++] = parseInt(F.substr(C, 2), 16)  //把F当做16进制的字符串,每取两位存一下}  }  return D  } 

j(C)方法才是用来加密的

//加密函数function j(D) {  h = new Array(8);  z = new Array(8);  A = w = 0;  p = true;  a = 0;  var B = D.length;  //获取要加密字符串的长度var E = 0;  a = (B + 10) % 8;  if (a != 0) {  a = 8 - a  }  //a为需要填充的字符个数o = new Array(B + a + 10); //填充为8的整数倍数组h[0] = ((f() & 248) | a) & 255;  //取f()的3~8位与a做或运算,这里把a存进去了,解密的时候可以推算出填充个数for (var C = 1; C <= a; C++) {  h[C] = f() & 255  //取f()的8位存入,填充用的,可以不管}  a++;  for (var C = 0; C < 8; C++) {  //初始化数组zz[C] = 0  }  E = 1;  while (E <= 2) {  if (a < 8) {  h[a++] = f() & 255;  //继续填充E++  }  if (a == 8) {  r()  //每次执行r(),a会重置为0}  }  var C = 0;  while (B > 0) {  if (a < 8) {  h[a++] = D[C++];  //把D数组的内容复制到h数组后面B--  }  if (a == 8) {  r()  //每次取出待加密数据的一个块,h[0]~h[7],送到r()处理}  }  E = 1;  while (E <= 7) {  if (a < 8) {  h[a++] = 0;  //填充0E++  }  if (a == 8) {  r()  }  }  return o  }

加密总体思路:填充算法-->QQCBC交织算法-->TEA算法,先看填充算法

(一)填充算法

参考这张图说明一下:


因为TEA加密只能加密定长的数据,所以QQ这里先分组,分组后给TEA加密,一个分组大小是8字节,所以填充完要是8字节的倍数

QQ在填充后的数据长度=原始数据长度+a+10

其中a的算法: 如果(B + 10) % 8=0,则a=0,如果(B + 10) % 8=!0则a=8-((B + 10) % 8)

整个数据区概况:1个字节标识a的长度(低位填充a,高位填充随机数)+a个字节的随机数填充+2位随机数填充+原始数据+7个字节0填充

数据区每取到8个字节就用r()函数加密一次

(二)、QQCBC交织算法

r()函数采用类似CBC模式

为什么是类似CBC,因为QQ的CBC模式比标准多了一步异或

QQCBC模式是这样的

与标准CBC多出来的异或在下图用红框标注出来了

QQCBC对应的代码如下:

//交织算法CBC加密function r() {  for (var B = 0; B < 8; B++) {  if (p) {  h[B] ^= z[B]  } else {  h[B] ^= o[w + B]  }  }  var C = l(h);  //CBC算法使用的加密器,TEA加密for (var B = 0; B < 8; B++) {  o[A + B] = C[B] ^ z[B];  //这里比标准的CBC算法多了一步异或z[B] = h[B]  }  w = A;  A += 8;  a = 0;  p = false  }  

图中的加密器使用的是16轮标准TEA加密,这个QQ没有改

(三)、TEA算法

标准TEA算法的图可以参考我之前写过的:TEA、XTEA、XXTEA加密解密算法

为了文章的完整性,这里也贴一下,图是一轮加密的描述

QQ的TEA用的16轮加密,标准用的32轮,常数delta=0x9e3779b9十进制就是2654435769,存储加密结果的时候使用的是网络序,代码如下

//tea加密算法主体function l(B) {  //u是CBC算法加密器对应的key,也就是tea对应的keyvar C = 16;  //16轮var H = k(B, 0, 4);  //取B[0]~B[3],形成字符串,B[0]在前,TEA算法左边v0var G = k(B, 4, 4);  //TEA算法右边v1var J = k(u, 0, 4);  //TEA秘钥k1 var I = k(u, 4, 4);  //TEA秘钥k2var F = k(u, 8, 4);  //TEA秘钥k3var E = k(u, 12, 4);  //TEA秘钥k4var D = 0;  var K = 2654435769 >>> 0;  //无符号右移,TEA算法的delta常数while (C-- > 0) {  D += K;  D = (D & 4294967295) >>> 0;  H += ((G << 4) + J) ^ (G + D) ^ ((G >>> 5) + I);  //计算TEA左边H = (H & 4294967295) >>> 0;  G += ((H << 4) + F) ^ (H + D) ^ ((H >>> 5) + E);  G = (G & 4294967295) >>> 0  }  var L = new Array(8);  b(L, 0, H);  b(L, 4, G);  return L  }  

(四)、常见问题

1.加密同一个明文结果不一样
QQ在实现加密的时候用了随机数填充,填充之后的数据区不一样,加密的明文自然不一样,填充用到的f()产生随机数,部分网上的实现可能为了比较算法结果固定了这个随机数,这时候密文结果就唯一了。密文解密时这些填充进去的随机数不影响解密
2.末尾填充7个字节0的作用
解密时校验解密的字符串是否正确
3.tea算法里的delta,tea解密算法里的sum取值
delta=(2^32)*黄金分割数0.618
sum = delta << 3; //32轮运算,是2的5次方,delta左移4位;16轮运算,是2的4次方,delta左移3位;8轮运算,是2的3次方,delta左移2位

4.自匿名函数中几个全局变量的作用

    var u = '',a = 0, h = [],z = [], A = 0,w = 0,o = [], v = [], p = true;  //u是初始秘钥,由initkey方法负责初始化,用于tea算法加密使用//z为交织算法CBC中的初始向量IV或上一个密文块//h为交织算法CBC中的明文块,计算过程中没有存所有明文h[0]~h[7]只存当前要计算的明文块//o为交织算法CBC中的密文,其中o[w + 0] ~o[w + 7]为第w个密文块//p标识是否为CBC中的明文块的第一块

5.自匿名函数的其他调用方法

TEA.initkey("111")可以改写为window.TEA.initkey("111"),其他以此类推。因为自匿名函数传了window参数进去,所以这些方法也是window对象的函数。

根据腾讯公开的JS文件分析QQTEA算法相关推荐

  1. 记一次js文件AES加密的key与iv逆向分析

    文章目录 前言 一.AES算法介绍 二.js文件代码 1.util.js文件 2.aes.js文件 三.代码分析 1.分析加密调用及过程 2. 分析e(key),n(iv)生成的过程 总结 前言 最近 ...

  2. 农产品价格数据可视化展示分析(附各省js文件)

    Flask+echarts做多图联动查询界面: 1.农产品价格数据/空气质量指数AQI可视化展示分析,使用echarts和pyecharts实现一个可视化的界面,数据源是我之前发给你们的农产品价格变动 ...

  3. yii 加载php文件,Yii2框架加载css和js文件的方法分析

    本文实例讲述了Yii2框架加载css和js文件的方法.分享给大家供大家参考,具体如下: 1.第一步是要把我们的css.js文件放到web目录下 2.第二步修改assets/AppAsset.php文件 ...

  4. 腾讯视频Node.js服务是如何支撑国庆阅兵直播高并发的?

    导语 | 上个月,我有幸参与了腾讯视频国庆阅兵直播页面开发的相关工作,最终,累计观看2.38亿人次,经受住了高并发的考验.在参于Glama框架的开发维护及平时基础建设相关讨论实践中,对高并发有一些部分 ...

  5. 腾讯视频 Node.js 服务是如何支撑国庆阅兵直播高并发的?

    导语 | 上个月,我有幸参与了腾讯视频国庆阅兵直播页面开发的相关工作,最终,累计观看2.38亿人次,经受住了高并发的考验.在参于Glama框架的开发维护及平时基础建设相关讨论实践中,对高并发有一些部分 ...

  6. JS逆向分析新浪某站登录处RSA加密

    文章目录 前言 RSA加解密 核心思想 Pyhon实现 NoPadding 新浪网实战 JS加密分析 JS函数调试 Py调用脚本 BurCrypto爆破 插件介绍 实战案例 总结 前言 在渗透测试过程 ...

  7. Eclipse编辑jsp、js文件时,经常出现卡死现象解决汇总

    使用Eclipse编辑jsp.js文件时,经常出现卡死现象,在网上百度了N次,经过N次优化调整后,卡死现象逐步好转,具体那个方法起到作用,不太好讲.将所有用过的方法罗列如下: 1.取消验证 windo ...

  8. js文件里获取路由 vue_「如何优雅的使用Vue?」不可不知的Vue实战技巧

    作者: CHICAGO 转发连接:https://juejin.im/post/5e475829f265da57444ab10f 前言 在大家都会用vue的时代,我们又如何去区别是新手小白还是资深vu ...

  9. js文件引用 webpack_想了解Webpack,看这篇就够了

    摘要:Webpack是一种前端资源构建工具,一个静态模块打包器. 1. 摘要 Webpack是一种前端资源构建工具,一个静态模块打包器.在Webpack看来,前端的所有资源文件(js/json/css ...

最新文章

  1. linux ftp登录命令_Linux使用pinky命令查询登录用户信息
  2. 排好序的数组中,找出两数之和为m的所有组合
  3. 量产 php是什么,php文件怎么打开?下错的?
  4. 重磅发布 | 2021 年 OpenAtom XuperChain 开源技术路径
  5. javascript 校验 非空_JavaScript_form表单非空验证;
  6. PC如何控制device进入suspend模式
  7. 模型的搜索和优化方法综述:
  8. C# WinForm中获取当前程序运行目录的方法
  9. CAN总线很难吗?CAN总线看不懂是不可能的!
  10. PHP之MVC项目实战
  11. 如何在Linux上安装设备驱动程序
  12. linux df 查看磁盘剩余空间,du查看文件占用多少空间,rm -rf 删除文件 mkdir -p创建目录(含父级)
  13. 【源码】手把手教你用Python实现Vivado和ModelSim仿真自动化
  14. 嵌入式常见 c语言笔试题
  15. linux查看日志相关命令
  16. 【Unity3D日常开发】新建2D、3D场景,新建场景没有灯光等问题
  17. Centos 在 Selenium 使用中的异常:chrome not reachable
  18. Stm32(寄存器)通道一--输出占空比50%的PWM
  19. C语言实用小技巧合集(持续更新)
  20. Flash Socket 的基本通讯协议流程例子

热门文章

  1. 工程小白问题:数采网关、智慧网关、物联网关、工业网关、DTU透传网关、边缘网关、协议网关、通讯管理机、中控网关、LORA网关、PROFIBUS网关、HART网关,都啥区别?如何判断是否符合工程要求?
  2. 【Golang】Golang基本介绍
  3. Maven运行测试用例
  4. “九”答不可 | 量子物理学为什么这么诡异?
  5. 【IC萌新虚拟项目】ppu模块的编译环境搭建与RTL编译
  6. C++课程设计:航空客运订票系统
  7. Github加速访问镜像站2022年12月更新
  8. Spring Webflux - 03 Webflux编程模型
  9. 前端使用mockjs模拟接口数据
  10. 游轮、游艇船用控制系统NMEA2000航空插头连接器