在現代Web應用安全分析中,加密算法的識別是JavaScript逆向工程的關鍵環節。本文將詳細介紹如何在逆向工程中判斷JavaScript代碼使用的是對稱加密還是非對稱加密。
一、加密算法基礎概念
1. 對稱加密 (Symmetric Encryption)
-
特點:加密和解密使用相同的密鑰
-
常見算法:AES、DES、3DES、RC4、Blowfish
-
優點:加解密速度快,適合大數據量加密
-
缺點:密鑰分發困難
2. 非對稱加密 (Asymmetric Encryption)
-
特點:使用公鑰加密,私鑰解密(或反之)
-
常見算法:RSA、ECC、ElGamal、DSA
-
優點:安全性高,無需共享密鑰
-
缺點:加解密速度慢,不適合大數據量
二、識別加密類型的關鍵指標
1. 密鑰特征識別法
// 對稱加密特征 - 通常只有一個密鑰
const key = "abcdef1234567890"; // 固定長度的密鑰
const iv = "1234567890abcdef"; // 初始化向量(IV)// 非對稱加密特征 - 明顯區分公鑰和私鑰
const publicKey = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...`;
const privateKey = `-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAA...`;
判斷要點:
-
對稱加密:通常有1個密鑰+可能的IV
-
非對稱加密:成對出現的公鑰/私鑰,結構明顯(PEM格式)
2. 加密函數調用識別法
對稱加密常見模式:
// AES加密典型調用
const encrypted = CryptoJS.AES.encrypt("plaintext", key, { iv: iv, mode: CryptoJS.mode.CBC }
).toString();
非對稱加密常見模式:
// RSA加密典型調用
const encrypt = new JSEncrypt();
encrypt.setPublicKey(publicKey);
const encrypted = encrypt.encrypt("plaintext");
判斷要點:
-
對稱加密:通常直接使用密鑰進行加密
-
非對稱加密:需要先設置公鑰/私鑰
3. 密鑰長度識別法
// 對稱加密密鑰長度
const aesKey = "0123456789abcdef"; // 16字節(128位)
const desKey = "abcdefgh"; // 8字節(64位)// 非對稱加密密鑰長度
const rsaKey = `-----BEGIN RSA PUBLIC KEY-----
MIIBCgKCAQEAx3j6...`; // 通常1024/2048位
判斷要點:
-
對稱加密:密鑰長度固定(AES:128/192/256位)
-
非對稱加密:密鑰長度較長(RSA通常≥1024位)
三、實戰識別步驟
步驟1:搜索加密關鍵詞
在代碼中搜索以下關鍵詞:
// 通用關鍵詞
encrypt, decrypt, cipher, crypto, encode, decode// 對稱加密關鍵詞
AES, DES, 3DES, RC4, Blowfish,
CBC, ECB, CFB, OFB, CTR, GCM, // 加密模式
iv, initializationVector, salt, // 相關參數// 非對稱加密關鍵詞
RSA, ECC, ElGamal, DSA,
publicKey, privateKey,
sign, verify, // 簽名相關
-----BEGIN (PUBLIC|PRIVATE) KEY-----
步驟2:分析加密庫使用
常見加密庫特征:
-
對稱加密庫:
-
CryptoJS (常見AES實現)
-
sjcl (斯坦福JS加密庫)
-
WebCrypto API (現代瀏覽器內置)
-
-
非對稱加密庫:
-
JSEncrypt (RSA實現)
-
forge (多種算法支持)
-
node-rsa (Node.js環境)
-
識別示例:
// 如果看到這些初始化,很可能是非對稱加密
const crypt = new JSEncrypt();
const rsa = new RSAKey();// 如果看到這些,很可能是對稱加密
const encrypted = CryptoJS.AES.encrypt(...);
const cipher = forge.cipher.createCipher('AES-CBC', key);
步驟3:跟蹤密鑰來源
// 對稱加密密鑰通常:
// 1. 硬編碼在代碼中
// 2. 從服務器獲取
// 3. 通過密鑰派生函數(PBKDF2)生成// 非對稱加密密鑰通常:
// 1. 以PEM格式存儲
// 2. 通過證書加載
// 3. 動態生成(如RSA密鑰對)
四、典型案例分析
案例1:對稱加密識別
// 典型AES加密實現
function encryptData(data) {const key = CryptoJS.enc.Utf8.parse("1234567890abcdef");const iv = CryptoJS.enc.Utf8.parse("abcdef1234567890");const encrypted = CryptoJS.AES.encrypt(data, key, {iv: iv,mode: CryptoJS.mode.CBC,padding: CryptoJS.pad.Pkcs7});return encrypted.toString();
}
識別特征:
-
使用CryptoJS庫
-
明確的key和iv
-
指定了加密模式(CBC)和填充方式(Pkcs7)
-
單一密鑰
案例2:非對稱加密識別
// 典型RSA加密實現
function rsaEncrypt(data) {const encryptor = new JSEncrypt();encryptor.setPublicKey(`-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz6XQhVj7JY...-----END PUBLIC KEY-----`);return encryptor.encrypt(data);
}
識別特征:
-
使用JSEncrypt庫
-
明顯的PEM格式公鑰
-
設置公鑰后加密
-
沒有對稱加密的iv參數
五、進階識別技巧
1. 加密模式識別
// 對稱加密常見模式特征
{mode: CryptoJS.mode.CBC, // 需要IVmode: CryptoJS.mode.ECB, // 不需要IVmode: CryptoJS.mode.GCM // 認證加密
}// 非對稱加密通常不指定模式
2. 加密操作上下文分析
-
對稱加密常見場景:
-
大量數據加密
-
通信內容加密
-
本地存儲加密
-
-
非對稱加密常見場景:
-
密鑰交換
-
數字簽名
-
小數據量加密
-
3. 性能特征分析
// 非對稱加密通常只加密小塊數據
rsaEncrypt(JSON.stringify({ token: "abc123" }));// 對稱加密可能加密大量數據
aesEncrypt(largeFileContent);
六、工具輔助識別
1. Chrome開發者工具
-
在Sources面板搜索加密關鍵詞
-
使用XHR斷點捕獲加密請求
2. Frida動態插樁
// 監控CryptoJS調用
Interceptor.attach(Module.findExportByName("libcrypto.so", "AES_encrypt"), {onEnter: function(args) {console.log("AES加密調用 detected");}
});
3. Burp Suite觀察
-
觀察請求特征:
-
對稱加密:數據長度與明文成比例
-
非對稱加密:固定長度輸出(如RSA 2048位總是256字節)
-
七、總結判斷流程圖
graph TDA[發現加密代碼] --> B{有公鑰/私鑰?}B -->|是| C[非對稱加密]B -->|否| D{單一密鑰+IV?}D -->|是| E[對稱加密]D -->|否| F[可能是哈希或其它]
快速判斷口訣:
-
一鑰加解是對稱
-
公私分明非對稱
-
密鑰較短是對稱
-
PEM格式非對稱
-
模式IV是對稱
-
簽名必是非對稱
掌握這些識別技巧,你就能在JavaScript逆向工程中快速判斷出使用的是對稱加密還是非對稱加密算法,為后續的深入分析打下基礎。