JavaScript加密算法特征识别指南
详细介绍各种JavaScript加密算法的特征和识别方法,包括BASE64、MD5、SHA、AES、DES等常见加密算法的特征分析
JavaScript加密算法特征识别指南
在JavaScript逆向分析中,识别加密算法是一个关键步骤。本文将介绍各种常见加密算法的特征,帮助你快速识别代码中使用的加密方法。
BASE64编码特征
1. 输出特征
// BASE64编码的特征
const base64Pattern = /^[A-Za-z0-9+/=]+$/;
// 典型的BASE64字符串示例
"SGVsbG8gV29ybGQ=" // "Hello World"的BASE64编码
"aHR0cHM6Ly9leGFtcGxlLmNvbQ==" // URL的BASE64编码
// 特征:
// 1. 只包含A-Z、a-z、0-9、+、/、=字符
// 2. 长度是4的倍数
// 3. =号只会出现在末尾,最多2个
2. 代码特征
// BASE64编码的常见代码特征
btoa(str) // 原生编码函数
atob(str) // 原生解码函数
// 自定义实现特征
const base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
str.replace(/=/g, ''); // 去除填充的等号
MD5算法特征
1. 输出特征
// MD5的特征
const md5Pattern = /^[a-f0-9]{32}$/;
// MD5输出示例
"d41d8cd98f00b204e9800998ecf8427e" // 空字符串的MD5
"e10adc3949ba59abbe56e057f20f883e" // "123456"的MD5
// 特征:
// 1. 固定32位长度
// 2. 只包含小写字母a-f和数字0-9
// 3. 输出长度固定,输入长度不限
2. 代码特征
// MD5算法的常见代码特征
function md5(str) {
// 特征1: 循环左移操作
function rol(num, cnt) {
return (num << cnt) | (num >>> (32 - cnt));
}
// 特征2: 四个常量
const A = 0x67452301;
const B = 0xEFCDAB89;
const C = 0x98BADCFE;
const D = 0x10325476;
// 特征3: 64个常量K数组
const K = [
0xd76aa478, 0xe8c7b756, /* ... */
];
}
SHA系列算法特征
1. 输出特征
// SHA系列的特征
const sha1Pattern = /^[a-f0-9]{40}$/; // SHA1
const sha256Pattern = /^[a-f0-9]{64}$/; // SHA256
const sha512Pattern = /^[a-f0-9]{128}$/; // SHA512
// 示例输出
"da39a3ee5e6b4b0d3255bfef95601890afd80709" // SHA1空字符串
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" // SHA256空字符串
// 特征:
// 1. SHA1: 40位十六进制
// 2. SHA256: 64位十六进制
// 3. SHA512: 128位十六进制
2. 代码特征
// SHA系列的代码特征
function sha256(str) {
// 特征1: 初始哈希值(每种SHA算法都不同)
const H = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
];
// 特征2: 位运算操作
const ROTR = (n, x) => (x >>> n) | (x << (32 - n));
const Ch = (x, y, z) => (x & y) ^ (~x & z);
const Maj = (x, y, z) => (x & y) ^ (x & z) ^ (y & z);
}
AES加密特征
1. 输出特征
// AES加密输出特征
// Base64编码的AES加密结果示例
"U2FsdGVkX1+9X9z1nWq4vnpyp2j7D5P0..." // 带Salt的AES
"d2H8qp1Znr5Rd3PR+0..." // 普通AES
// 特征:
// 1. 输出长度是16的倍数(如果Base64编码则不适用)
// 2. 常见模式:ECB、CBC、CFB、OFB、CTR
// 3. 常见填充:PKCS7、PKCS5、ZeroPadding
2. 代码特征
// AES代码特征
function aes() {
// 特征1: S盒
const sBox = [
0x63, 0x7c, 0x77, 0x7b, /* ... */
];
// 特征2: 轮常量
const rCon = [
0x00, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36
];
// 特征3: 密钥扩展
function keyExpansion(key) {
// 4x4状态矩阵
// 10/12/14轮变换
}
}
DES加密特征
1. 输出特征
// DES加密输出特征
// Base64编码的DES加密结果示例
"FE3592A45D91E93B..." // 标准DES
"A7B9C4D2E3F1..." // 3DES
// 特征:
// 1. 输出长度是8的倍数
// 2. 如果是3DES,密钥长度是24字节
// 3. 标准DES密钥长度8字节
2. 代码特征
// DES代码特征
function des() {
// 特征1: IP初始置换表
const IP = [
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
// ...
];
// 特征2: S盒
const SBOX = [
[
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
// ...
],
// 共8个S盒
];
// 特征3: 特征函数F
function f(r, k) {
// 扩展置换
// S盒替换
// P盒置换
}
}
RSA加密特征
1. 输出特征
// RSA加密输出特征
// Base64编码的RSA加密结果示例
"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC..." // 公钥
"MIIC3TBXBgkqhkiG9w0BAQEFAAOCAl4wggJaAgEAAkEA..." // 私钥
// 特征:
// 1. 输出长度与密钥长度相关
// 2. 公钥、私钥有固定格式(PEM格式)
// 3. 常见密钥长度:1024、2048、4096位
2. 代码特征
// RSA代码特征
function rsa() {
// 特征1: 大数运算
BigInt('0x' + hexString);
// 特征2: 模幂运算
function modPow(base, exponent, modulus) {
// 快速幂算法实现
}
// 特征3: 公私钥参数
const n = '...'; // 模数
const e = '...'; // 公钥指数(通常是65537)
const d = '...'; // 私钥指数
}
常见混淆手段
1. 字符串混淆
// 特征:字符串被分割和重组
const _0x1234 = ['636', 'f39', '72b'];
const key = _0x1234[0] + _0x1234[1];
// 特征:Unicode编码
const algorithm = '\u0042\u0041\u0053\u0045\u0036\u0034'; // "BASE64"
2. 算法名混淆
// 特征:算法名被替换或拆分
const enc = window['btoa']; // BASE64编码
const hash = window['MD' + '5']; // MD5算法
// 特征:自定义名称
const secure = function(str) {
return window.CryptoJS.MD5(str);
}
识别技巧
1. 输入输出分析
// 1. 观察输入长度与输出长度的关系
function analyzeIO(func, input) {
const output = func(input);
console.log({
inputLength: input.length,
outputLength: output.length,
outputPattern: output.match(/^[A-Za-z0-9+/=]+$/) ? 'BASE64?' :
output.match(/^[a-f0-9]{32}$/) ? 'MD5?' :
'Unknown'
});
}
2. 特征常量检测
// 2. 查找算法特征常量
function findConstants(code) {
// 查找S盒
if (code.includes('0x63, 0x7c, 0x77, 0x7b')) {
console.log('可能是AES算法');
}
// 查找初始化向量
if (code.includes('0x67452301')) {
console.log('可能是MD5算法');
}
}
3. 代码结构分析
// 3. 分析代码结构特征
function analyzeStructure(code) {
// 检查是否有特征函数
if (code.includes('rol') || code.includes('ROTR')) {
console.log('可能是哈希算法');
}
// 检查是否有分组操作
if (code.includes('blockSize') || code.includes('chunkSize')) {
console.log('可能是分组加密算法');
}
}
总结
识别加密算法需要从多个角度进行:
- 输出特征(长度、字符集)
- 代码特征(常量、函数结构)
- 算法特有的操作(位运算、矩阵变换等)
- 混淆方式的识别
建议建立自己的特征库,收集常见的算法特征,这样可以更快地识别出代码中使用的加密方法。
参考资源
如果你在识别加密算法时遇到问题,欢迎在评论区讨论交流。
评论