本文旨在講解網(wǎng)易云的加密算法,僅供參考,請不要用于非法用途。截止本文發(fā)布時間,此加密算法仍然適用。查看原文
網(wǎng)易云音樂前段時間更改了api接口,將以前的GET請求變成了POST請求,并且POST的參數(shù)是加密后的參數(shù),具體請看圖片。為了突破爬蟲限制,需要破解其中的加密算法。
改進后POST請求參數(shù)如下:

用于加密的核心代碼如下(代碼在http://s3.music.126.net/sep/s/2/core.js?06b50101e4968eb701d6b24cd94b48d2第11173行開始):
生成隨機16位字符串
function a(a) {
var d, e, b = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789", c = "";
for (d = 0; a > d; d += 1)
e = Math.random() * b.length,
e = Math.floor(e),
c += b.charAt(e);
return c
}
AES加密函數(shù)
function b(a, b) {
var c = CryptoJS.enc.Utf8.parse(b)
, d = CryptoJS.enc.Utf8.parse("0102030405060708") 偏移量已知
, e = CryptoJS.enc.Utf8.parse(a)
, f = CryptoJS.AES.encrypt(e, c, {
iv: d,
mode: CryptoJS.mode.CBC
});
return f.toString()
}
RSA加密函數(shù)
function c(a, b, c) {
var d, e;
return setMaxDigits(131),
d = new RSAKeyPair(b,"",c),
e = encryptedString(d, a)
}
主入口
function d(d, e, f, g) {
var h = {}
, i = a(16);
return h.encText = b(d, g), 密鑰g已知
h.encText = b(h.encText, i),
h.encSecKey = c(i, e, f), e和f已知
h
}
其中入口在function d處,傳入的參數(shù)為:

d是正常的請求參數(shù)
e和f是RSA中加密所需的key和modulus
g是AES加密的key
從function d中可以看出加密流程,先隨機生成一個16位的密鑰,將正常的請求參數(shù)與g先加密一次,再與16位的密鑰加密一次,此結(jié)果為POST參數(shù)的param。由于密鑰是在客戶端上隨機產(chǎn)生的,所以要將隨機密鑰進行一次RSA加密后作為encSecKey參數(shù)POST到服務(wù)端。
所以,整體加密方式為,客戶端生成16位密鑰,將請求參數(shù)加密兩次后,將參數(shù)加密后的結(jié)果和密鑰加密后的結(jié)果一起傳到服務(wù)端完成解密過程。