Windows 11 下用 Node.js 和 crypto-js 逆向分析网站登录密码加密,保姆级实战拆解
在当今的Web安全领域,前端加密已成为保护用户敏感数据的标配方案。当我们面对一个加密的登录请求时,如何从黑盒状态一步步揭开其加密逻辑?本文将带你深入实战,从浏览器开发者工具的初步观察,到Node.js环境的完整复现,构建一套可落地的逆向分析方法论。
1. 逆向工程基础准备
逆向分析需要一套完整的工具链支持。在Windows 11环境下,我们需要配置以下核心组件:
- Node.js环境:选择LTS版本(建议18.x+),这是运行JavaScript代码的基础平台
- crypto-js库:提供标准加密算法实现,与前端常用的加密库保持一致
- 开发者工具:Chrome DevTools的网络面板和调试功能是核心分析利器
配置环境时常见的问题包括npm源访问缓慢,推荐使用以下命令配置国内镜像:
npm config set registry https://registry.npmmirror.com/注意:部分企业内网环境可能需要额外配置代理,但本文不涉及任何网络访问工具的讨论
2. 加密入口定位技巧
当提交登录表单时,密码字段通常会在以下位置被处理:
- 表单提交事件的拦截处理
- XMLHttpRequest或fetch请求的拦截器
- 第三方安全SDK的自动加密
在Chrome DevTools中,可以通过以下步骤快速定位:
- 打开Network面板,筛选XHR请求
- 查看登录请求的Payload,确认密码字段是否已加密
- 在Sources面板搜索关键词如
encrypt、CryptoJS、AES等
典型加密特征包括:
| 特征类型 | 示例 | 说明 |
|---|---|---|
| 固定长度 | A7428361DEF118... | AES加密结果通常为16/32字节的十六进制 |
| 特殊前缀 | $1$salt$hash | 可能使用自定义的加密方案标识 |
| 请求参数 | _sign=md5(value) | 常见于API签名验证机制 |
3. 加密算法逆向解析
以某网站登录为例,通过调试发现其加密逻辑如下:
const key = CryptoJS.enc.Utf8.parse("2017110912453698..."); const iv = CryptoJS.enc.Utf8.parse('2017110912453698'); function encrypt(word) { let srcs = CryptoJS.enc.Utf8.parse(word); let encrypted = CryptoJS.AES.encrypt(srcs, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 }); return encrypted.ciphertext.toString().toUpperCase(); }关键参数解析:
- key:32字节的UTF8编码字符串,实际使用256位AES加密
- iv:16字节初始化向量,采用CBC加密模式必需
- mode:CBC模式需要iv,而ECB模式则不需要
- padding:PKCS7是AES最常用的填充方案
4. Node.js环境完整复现
在本地复现加密过程需要严格还原前端环境:
- 安装crypto-js:
npm install crypto-js- 构建加密模块:
const CryptoJS = require("crypto-js"); const AESEncrypt = (password) => { const key = CryptoJS.enc.Utf8.parse("2017110912453698..."); const iv = CryptoJS.enc.Utf8.parse('2017110912453698'); const encrypted = CryptoJS.AES.encrypt( CryptoJS.enc.Utf8.parse(password), key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 } ); return encrypted.ciphertext.toString().toUpperCase(); }; // 测试加密 console.log(AESEncrypt("123456")); // 应输出:A7428361DEF118911783F446A129FFCE常见问题排查:
- 编码问题:确保所有字符串都统一使用UTF8编码
- 结果不一致:检查加密模式、填充方案等参数是否完全一致
- 密钥错误:确认密钥长度是否符合算法要求(AES-256需要32字节)
5. 高级逆向技巧进阶
对于更复杂的加密场景,可以采用以下进阶方法:
动态Hook技术:
// 在Console中重写加密函数 const oldEncrypt = CryptoJS.AES.encrypt; CryptoJS.AES.encrypt = function() { console.log("加密参数:", arguments); return oldEncrypt.apply(this, arguments); };调用栈分析:
- 在加密函数处设置断点
- 查看Call Stack面板的调用链
- 回溯到业务逻辑的入口点
反混淆策略:
- 使用AST解析工具处理压缩代码
- 还原变量名和函数名
- 特别注意Webpack等打包工具的模块加载逻辑
6. 安全防御与对抗
作为开发者,如何防止自己的加密逻辑被逆向?可以考虑以下防护方案:
- 动态密钥:通过服务端接口获取临时密钥
- 代码混淆:使用Webpack、Terser等工具压缩代码
- 环境检测:校验执行环境是否在浏览器中
- 多阶段加密:组合使用RSA+AES等不同算法
但需要明确的是,前端加密本质上属于"防君子不防小人"的方案,真正的安全应该建立在HTTPS传输和服务器端验证的基础上。