JS逆向:由 words 、sigBytes 引发的一系列思考与实践
【作者主页】:小鱼神1024
【擅长领域】:JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等
在做JS逆向时,你是否经常看到 words
和 sigBytes
这两个属性呢,比如:
{words: [2003644449, 1081552243, 594308145, 1718382376], sigBytes: 16
}
如果发现了它们的踪迹,那恭喜你了。基本可以确定,网站是使用 crypto-js
库中某一个加密算法实现加密的。
words 、sigBytes 它们是什么
在 crypto-js
这个流行的 JavaScript
加密库中,words
和 sigBytes
是 CryptoJS.lib.WordArray
对象的两个重要属性。
words
数组是 WordArray
对象的主体,它用于存储加密数据。在 crypto-js 中,一个 word
是由32位(或者说是4个字节)组成的,因此每个元素在 words 数组中实际上可以表示4个字节的数据。
在计算机系统中,一个32位的整数可以存储从-2,147,483,648到2,147,483,647的整数值(如果是有符号整数),或者从0到4,294,967,295(如果是无符号整数)。这种表示范围是因为32位可以表示2^32(即4,294,967,296)个不同的值。
补充
在计算机和信息技术中,32位(4字节)是一个常用的数据大小单位,用来表示数据的存储或处理容量。具体来讲:
- 1位(bit):是计算机数据的最基本单位,代表一个二进制数字,即0或1。
- 1字节(Byte):通常由8位组成,是基本的数据存储单位。1字节可以表示0到255(或者在二进制中是00000000到11111111)之间的一个数值。
- 32位:则相当于4字节(4 Bytes),因为1字节是8位,所以4字节就是4 * 8 = 32位。
如何生成 WordArray 对象
两种解决办法:
通过 CryptoJS.enc.Utf8.parse 生成
如果已知utf8编码的明文,则可以使用 CryptoJS.enc.Utf8.parse
方法生成 WordArray
对象。
const CryptoJS = require("crypto-js");// 生成 WordArray 对象
const keyWordArray = CryptoJS.enc.Utf8.parse("wm0!@w-s#ll1flo(");
console.log(keyWordArray);
通过 CryptoJS.lib.WordArray.create 生成
const CryptoJS = require("crypto-js");
const words = [2003644449, 1081552243, 594308145, 1718382376]; // 32位整数数组(words数组)
const sigBytes = 16;// 使用 CryptoJS 转换字节数组到 WordArray
const keyWordArray = CryptoJS.lib.WordArray.create(words, sigBytes);console.log(keyWordArray);
如何将 WordArray 转化为 UTF-8 字符串
const CryptoJS = require("crypto-js");
const wordArrayBytes = {words: [ 2003644449, 1081552243, 594308145, 1718382376 ],sigBytes: 16
};// 将 WordArray 转换为 UTF-8 字符串
const key = CryptoJS.enc.Utf8.stringify(wordArrayBytes);
console.log(key);// wm0!@w-s#ll1flo(
如何将 WordArray 转化为十六进制Hex
const CryptoJS = require("crypto-js");
const wordArrayBytes = {words: [ 2003644449, 1081552243, 594308145, 1718382376 ],sigBytes: 16
};// 将 WordArray 转换为十六进制Hex
const key = CryptoJS.enc.Hex.stringify(wordArrayBytes);
console.log(key);// 776d302140772d73236c6c31666c6f28
那如何判断一个字符串是否为有效的十六进制字符串,可以检查以下几点:
-
字符串长度:十六进制字符串的长度应该是偶数。
-
字符范围:十六进制字符串只能包含 0-9 以及 a-f 和 A-F 这些字符。
可以编写一个函数来实现这个逻辑:
// 判断一个字符串是否为十六进制字符串的函数
function isHexString(str) {// 检查长度是否为偶数if (str.length % 2 !== 0) {return false;}// 使用正则表达式检查字符串是否只包含合法的十六进制字符(0-9, a-f, A-f)const hexRegex = /^[0-9a-fA-F]+$/;return hexRegex.test(str);
}// 示例测试
const testHexString1 = "776d302140772d73236c6c31666c6f28";
const testHexString2 = "1a2b3g4d5e"; // 包含非法字符 'g'
const testHexString3 = "123"; // 长度为奇数console.log(isHexString(testHexString1)); // 输出:true
console.log(isHexString(testHexString2)); // 输出:false
console.log(isHexString(testHexString3)); // 输出:false
WordArray整数数组、Hex十六进制、ByteArray字节数组、UTF-8字符串之间的相互转换
// 判断一个数组是否为字节数组(每个元素为0到255之间的整数)
function isByteArray(arr) {// 首先检查是否为数组if (!Array.isArray(arr)) {return false;}// 检查每个元素是否为0到255之间的整数for (let i = 0; i < arr.length; i++) {if (typeof arr[i] !== 'number' || arr[i] < 0 || arr[i] > 255 || !Number.isInteger(arr[i])) {return false;}}return true;
}// 将字节数组转换为十六进制字符串的函数
function bytesToHex(bytes) {if (!isByteArray(bytes)) {throw new Error('输入必须是字节数组');}return bytes.map(byte => byte.toString(16).padStart(2, '0')).join('');
}// 将十六进制字符串转换为字节数组的函数
function hexToBytes(hex) {let bytes = [];for (let c = 0; c < hex.length; c += 2) {bytes.push(parseInt(hex.substr(c, 2), 16));}return bytes;
}// 将32位整数数组(words数组)转换为字节数组的函数
function wordsToBytes(words) {let bytes = [];for (let i = 0; i < words.length; i++) {let word = words[i];bytes.push((word >> 24) & 0xFF);bytes.push((word >> 16) & 0xFF);bytes.push((word >> 8) & 0xFF);bytes.push(word & 0xFF);}return bytes;
}// 将字节数组转换为UTF-8字符串的函数
function bytesToStringUTF8(bytes) {if (!isByteArray(bytes)) {throw new Error('输入必须是字节数组');}return new TextDecoder('utf-8').decode(new Uint8Array(bytes));
}let key = { words: [2003644449, 1081552243, 594308145, 1718382376], sigBytes: 16 };// 将key的words数组转换为字节数组
let keyBytes = wordsToBytes(key.words);// 将字节数组转换为十六进制字符串,测试使用
let keyHex = bytesToHex(keyBytes);// 打印key和iv的十六进制字符串
console.log("十六进制Hex:", keyHex);// 将十六进制字符串还原为字节数组,以确保转换过程的无损失和准确性,测试使用
let keyBytesFromHex = hexToBytes(keyHex);// 将字节数组转换为UTF-8字符串,得到最终的字符串表示
let keyString = bytesToStringUTF8(keyBytes);// 打印key和iv的UTF-8字符串表示
console.log("字符串UTF-8:", keyString);
用 Uint8Array 生成字节数组
Uint8Array 的特点包括以下几点:
-
无符号整数:Uint8Array 存储的是无符号的 8 位整数(0 到 255),因此每个元素的取值范围是从 0 到 255。这意味着每个元素可以表示一个字节的数据,适用于处理字节数据和二进制数据。
-
定长数组:Uint8Array 是一种定长数组,它的长度在创建时就已经确定,并且不能动态改变。这有助于提高操作效率和性能,尤其在处理大量数据时非常有用。
// 用 Uint8Array 生成字节数组
const uint8Array = Uint8Array.from([119, 109, 48, 33, 64,119, 45, 115, 35, 108,108, 49, 102, 108, 111,40
]);// 使用 TextDecoder 将 bytes 转换为字符串
const textDecoder = new TextDecoder();
const decodedString = textDecoder.decode(uint8Array);console.log(decodedString);// wm0!@w-s#ll1flo(
为什么 AES、DES等加密时,要先转化 WrodArray
// AES 加密
function encrypt(word) {// 转化为 WordArrayconst iv = CryptoJS.enc.Utf8.parse("0102030405060708");// 转化为 WordArrayconst key = CryptoJS.enc.Utf8.parse('wm0!@w-s#ll1flo(');const encrypted = CryptoJS.AES.encrypt(word, key, {iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7})return encrypted.toString();
}
转化为32位二进制数据再进行加密是出于以下几个主要原因:
-
加密算法的要求:几乎所有的现代加密算法,包括对称加密(如AES)和非对称加密(如RSA),在底层操作时都是以二进制数据形式工作的。这是因为加密算法在设计时需要操作位(bit)和字节(byte),而不是高级语言中的文本或数字等类型。因此,将数据转换为二进制形式是执行这些算法的必要步骤。
-
安全性增强:通过转换为二进制数据,可以确保在加密过程中原始数据的内容不会因其格式或结构而泄露信息。此外,某些加密方式(如块加密)要求数据以特定大小的块来处理。将数据预先转化为二进制形式,可以更容易地按块对数据进行操作和填充。
-
性能优化:直接对二进制数据进行操作比对高级数据类型(如字符串或对象)进行操作要有效率得多。加密和解密操作通常需要大量的数据处理工作,特别是在数据量大或需求高性能的应用场景中。预先将数据转换为二进制格式,可以最大限度地减少处理时间和资源消耗。
创作不易,动动您发财的小手,点赞关注一波,支持我创作更多对您有帮助的文章!
相关文章:
JS逆向:由 words 、sigBytes 引发的一系列思考与实践
【作者主页】:小鱼神1024 【擅长领域】:JS逆向、小程序逆向、AST还原、验证码突防、Python开发、浏览器插件开发、React前端开发、NestJS后端开发等等 在做JS逆向时,你是否经常看到 words 和 sigBytes 这两个属性呢,比如ÿ…...
计算机的错误计算(十五)
摘要 介绍历史上由于计算精度问题引起的灾难或事件。 今天换个话题,说说历史上曾经发生过的一些事件。 1961 年 , 美国麻省理工学院气象学家洛伦兹在仿真天气预报时 , 将 0.506127 舍入到 0.506 , 所得计算结果大相径庭 ! 这种“差之毫厘 , 谬以千里”的现象…...
制作img文件
安装软件包 sudo apt-get install dosfstools dump parted kpartx 创建空白img文件 sudo dd if/dev/zero ofraspberrypi.img bs1M count4000 给img文件分区 sudo parted raspberrypi.img --script -- mklabel msdos sudo parted raspberrypi.img --script -- mkpart primar…...
GB28181视频汇聚平台EasyCVR接入Ehome设备视频播放出现异常是什么原因?
多协议接入视频汇聚平台EasyCVR视频监控系统采用了开放式的架构,系统可兼容多协议接入,包括市场标准协议:国标GB/T 28181协议、GA/T 1400协议、JT808、RTMP、RTSP/Onvif协议;以及主流厂家私有协议及SDK,如:…...
Java利用poi实现word,excel,ppt,pdf等各类型文档密码检测
介绍 最近工作上需要对word,excel,ppt,pdf等各类型文档密码检测,对文件进行分类,有密码的和没密码的做区分。查了一堆资料和GPT都不是很满意,最后东拼西凑搞了个相对全面的检测工具代码类,希望能给需要的人带来帮助。 说明 这段…...
顺序表与链表学习笔记
顺序表及其结构定义 (1)结构定义 顺序存储: 顺序表的元素按顺序存储在一块连续的内存区域中,每个元素占用相同大小的存储空间。通过数组实现,每个元素可以通过下标快速访问。 存储密度高: 因为顺序表使用…...
2.SQL注入-字符型
SQL注入-字符型(get) 输入kobe查询出现id和邮箱 猜测语句,字符在数据库中需要用到单引号或者双引号 select 字段1,字段2 from 表名 where usernamekobe;在数据库中查询对应的kobe,根据上图对应上。 select id,email from member where usernamekobe;编写payload语…...
在Ubuntu 14.04上安装和配置Elasticsearch的方法
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 简介 Elasticsearch 是一个用于实时分布式搜索和数据分析的平台。它因易用性、强大功能和可扩展性而备受欢迎。 Elasticsearch 支持 R…...
C++:inline关键字nullptr
inline关键字 C中inline使用关键点强调 (1)inline是一种“用于实现的关键字”,而不是一种“用于声明的关键字”,所以关键字 inline 必须与函数定义体放在一起,而不是和声明放在一起 (2)如果希望在多个c文件中使用,则inline函数应…...
数字信号处理实验三(IIR数字滤波器设计)
IIR数字滤波器设计(2学时) 要求: 产生一复合信号序列,该序列包含幅度相同的28Hz、50Hz、100Hz、150Hz的单音(单频)信号;其中,50Hz及其谐波为工频干扰(注:采样…...
Why is Kafka fast?(Kafka性能基石)
Kafka概述 Why is kafka fast? 思考一下,当我们在讨论Kafka快的时候我们是在谈论什么呢?What does it even mean that Kafka is fast? 我们是在谈论kafka的低延迟(low latency)还是在讨论吞吐量(through…...
Linux下的SSH详解及Ubuntu教程
前言 SSH(Secure Shell)是一种用于计算机之间安全通信的协议,广泛应用于远程登录、系统管理和文件传输等场景。本文将详细介绍SSH在Linux系统(特别是Ubuntu)下的使用,包括安装、配置、密钥管理和常见应用&…...
MobPush HarmonyOS NEXT 版本集成指南
开发工具:DevEco Studio 集成方式:在线集成 HarmonyOS API支持:> 11 集成前准备 注册账号 使用MobSDK之前,需要先在MobTech官网注册开发者账号,并获取MobTech提供的AppKey和AppSecret,详情可以点击查…...
什么是封装?为什么要封装?
什么是封装? 封装是计算机科学中的一个重要概念,尤其在面向对象编程(OOP)中占据核心地位。封装主要指的是将数据(属性)和对这些数据的操作(方法)组合在一个单元中(我们称…...
远程桌面无法复制粘贴文件到本地怎么办?
远程桌面不能复制粘贴问题 Windows远程桌面为我们提供了随时随地访问文件和数据的便捷途径,大大提升了工作和生活的效率。然而,在使用过程中,我们也可能遇到一些问题。例如,在通过远程桌面传输文件时,常常会出现无法复…...
LeetCode 207. 课程表
思路:这是一道拓扑排序问题,拓扑排序听起来可能有点复杂,但实际上它是个相当直观的概念。想象一下,你有很多事情要做,但有些事情必须在另一些事情完成之后才能开始,就像你得先穿上袜子再穿鞋子 拓扑排序就…...
数据结构历年考研真题对应知识点(树的基本概念)
目录 5.1树的基本概念 5.1.2基本术语 【森林中树的数量、边数和结点数的关系(2016)】 5.1.3树的性质 【树中结点数和度数的关系的应用(2010、2016)】 【指定结点数的三叉树的最小高度分析(2022)】 5.1…...
Pytorch和Tensorflow安装【Win和Linux】
Ubuntu/win安装Pytorch和Tensorflow 说明: 这两种框架的搭建,均基于Anaconda进行搭建。先在系统中安装Anaconda软件。 一、Pytorch的搭建 windows安装 (1)搭建参考官网给的命令,pytorch官网 (2)下载地址:https://download.pytorch.org/whl/torch_stable.html 从上述…...
筑算网基石 创数智未来|锐捷网络闪耀2024 MWC上海
2024年6月26日至28日,全球科技界瞩目的GSMA世界移动大会(MWC 上海)在上海新国际博览中心(SNIEC)盛大召开。作为行业领先的网络解决方案提供商,锐捷网络以“筑算网基石 创数智未来”为主题,带来了…...
T4打卡 学习笔记
所用环境 ● 语言环境:Python3.11 ● 编译器:jupyter notebook ● 深度学习框架:TensorFlow2.16.1 ● 显卡(GPU):NVIDIA GeForce RTX 2070 设置GPU from tensorflow import keras from tensorflow.keras…...
抖音矩阵云混剪系统源码 短视频矩阵营销系统V2(全开源版)
>>>系统简述: 抖音阵营销系统多平台多账号一站式管理,一键发布作品。智能标题,关键词优化,排名查询,混剪生成原创视频,账号分组,意向客户自动采集,智能回复,多…...
zabbix报警机制
zabbix思路流程...
【Matlab】-- 飞蛾扑火优化算法
文章目录 文章目录 01 飞蛾扑火算法介绍02 飞蛾扑火算法伪代码03 基于Matlab的部分飞蛾扑火MFO算法04 参考文献 01 飞蛾扑火算法介绍 飞蛾扑火算法(Moth-Flame Optimization,MFO)是一种基于自然界飞蛾行为的群体智能优化算法。该算法由 Sey…...
全面体验ONLYOFFICE 8.1版本桌面编辑器
ONLYOFFICE官网 在当今的数字化办公环境中,选择合适的文档处理工具对于提升工作效率和团队协作至关重要。ONLYOFFICE 8.1版本桌面编辑器,作为一款集成了多项先进功能的办公软件,为用户提供了全新的办公体验。今天,我们将深入探索…...
建议csdn赶紧将未经作者同意擅自锁住收费的文章全部解锁,别逼我用极端手段让你们就范
前两天我偶然发现csdn竟然将我以前发表的很多文章锁住向读者收费才让看。 csdn这种无耻行径往小了说是侵犯了作者的版权著作权,往大了说这是在打击我国IT领域未来的发展,因为每一个做过编程工作的人都知道,任何一个程序员的学习成长过程都少不…...
Pycharm一些问题解决办法
研究生期间遇到关于Pycharm一些问题报错以及解决办法的汇总 ModuleNotFoundError: No module named sklearn’ 安装机器学习库,需要注意报错的sklearn是scikit-learn缩写。 pip install scikit-learnPyCharm 导包提示 unresolved reference 描述:模块…...
ONLYOFFICE 桌面编辑器 8.1 发布:全新 PDF 编辑器、幻灯片版式、增强 RTL 支持及更多本地化选项
目录 什么是ONLYOFFICE? ONLYOFFICE 主要特点包括: 官网信息: 1. 功能齐全的 PDF 编辑器 1.1 编辑 PDF 文本 1.2 插入和修改对象 1.3 创建和填写表单 2. 幻灯片版式功能 2.1 快速应用幻灯片版式 2.2 动画窗格的改进 3. 文档编辑、…...
Linux高并发服务器开发(六)线程
文章目录 1. 前言2 线程相关操作3 线程的创建4 进程数据段共享和回收5 线程分离6 线程退出和取消7 线程属性(了解)8 资源竞争9 互斥锁9.1 同步与互斥9.2 互斥锁 10 死锁11 读写锁12 条件变量13 生产者消费者模型14 信号量15 哲学家就餐 1. 前言 进程是C…...
Google发布Gemma 2轻量级开放模型 以极小的成本提供强大的性能
除了 Gemini 系列人工智能模型外,Google还提供 Gemma 系列轻量级开放模型。今天,他们发布了 Gemma 2,这是基于全新架构设计的下一代产品,具有突破性的性能和效率。 Gemma 2 有两种规格:90 亿 (9B) 和 270 亿 (27B) 个参…...
精品UI知识付费系统源码网站EyouCMS模版源码
这是一款知识付费平台模板,后台可上传本地视频,批量上传视频连接, 视频后台可设计权限观看,免费试看时间时长,会员等级观看,付费观看等功能, 也带软件app权限下载,帮助知识教育和软件…...
成都市网站建设公司/网络营销的盈利模式
参数传递:将主程序变量传递给子例程形式参数传递类型值传:子例程中参数变量的值的改变,不影响外部程序实际变量的值. DATA:A TYPE I VALUE 3,B TYPE I VALUE 6,C TYPE I. WRITE:A,A,B,B,C,C. PERFORM ADD USING A B CHANGING C. WRITE:/ SY-…...
专业网站建设专家/互联网营销模式
一、MyBatis 接口绑定方案及多参数传递 1、作用:实现创建一个接口后把mapper.xml由mybatis生成接口的实现类,通过调用接口对象就可以获取mapper.xml中编写的sql 2、后面:mybatis和spring整合时使用的是这个方案 3、实现步骤: 3.1 …...
大连市公众平台网站/网站注册搜索引擎的目的是
文章目录1.如何设置工程(指定Project)的SDK?2.IDEA中各种Setting的区别3.IDEA 配置全局的Maven设置4.设置编译的版本1.如何设置工程(指定Project)的SDK? 原项目的相关信息如下 接下来我修改它的项目名称为project-modify,指定该项目使用JDK1.7,并且设置该项目生成Class文件…...
做网站要排版吗/太原seo公司
centos7性能调优 tuned 守护进程会利用反映特定工作负载要求的调优配置文件,以静态和动态两种方式应用调优调整。 调优分为静态调优、动态调优 静态调优 tuned 守护进程会在服务启动时或选择新的调优配置文件时应用系统设置。静态调优会对配置文件中由 tuned 在运…...
福州自适应网站建设/海淀区seo全面优化
1.安装git2.如图所示:在AS 的File->Settings->Version Control->Git 配置git.exe命令路径,然后点击Test,提示successfully,则配置成功。3.在gitosc上创建仓库,获取仓库地址。4.创建AS项目。5.在AS中选择项目,…...
asp 网站支持多语言/seo页面优化的方法
Silverlight 1.0 終於推出正式版了,但這只是拉開這場瀏覽器平台戰爭的序幕而已,真正精彩的還在後頭,ScottGu在他的Blog上有以下這段話.Silverlight 1.1 will include a cross-platform version of the .NET Framework, and will enable a rich .NET development experience in …...