X-hub

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('可能是分组加密算法');
    }
}

总结

识别加密算法需要从多个角度进行:

  1. 输出特征(长度、字符集)
  2. 代码特征(常量、函数结构)
  3. 算法特有的操作(位运算、矩阵变换等)
  4. 混淆方式的识别

建议建立自己的特征库,收集常见的算法特征,这样可以更快地识别出代码中使用的加密方法。

参考资源

如果你在识别加密算法时遇到问题,欢迎在评论区讨论交流。

评论