网易云音乐加密分析
網(wǎng)易云音樂(lè)加密分析
網(wǎng)易云的加密網(wǎng)上已經(jīng)寫(xiě)爛了,并且網(wǎng)易云的程序員似乎并沒(méi)有更新加密的想法,這幾乎是唯一一家了,也許人家根本不在乎你能模擬加密。
當(dāng)初第一次你想網(wǎng)易云的時(shí)候,就遺留了一些問(wèn)題,不過(guò)當(dāng)時(shí)技術(shù)有限,湊湊別人的代碼倒也能實(shí)現(xiàn),現(xiàn)在回來(lái)再看,打算完整地分析一遍,解決當(dāng)時(shí)的疑惑。
首先加密位置很容易找到的。現(xiàn)在想來(lái),當(dāng)時(shí)為什么網(wǎng)易云JS分析也覺(jué)得這么有難度,我不理解。
hook的方法
要獲取這四個(gè)參數(shù)具體的值話,有三種辦法:
想使用一下第三種辦法,在瀏覽Source面板改完如下
控制臺(tái)輸出效果
加密函數(shù)
跟進(jìn)加密函數(shù),關(guān)鍵加密邏輯就幾行代碼
這里的d,e,f,g就是我們打印的那四個(gè)參數(shù)
函數(shù)a代碼很簡(jiǎn)單
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}生成16位隨機(jī)字符串,這個(gè)也是可以寫(xiě)死的,但是偽裝就裝得像一點(diǎn)。使用Python改寫(xiě)的話也是十分簡(jiǎn)單。
CHARS = string.ascii_letters + string.digitsdef random_str(cnt: int) -> str:return ''.join(random.choices(CHARS, k=cnt))b函數(shù),AES加密,CBC模式,直接調(diào)庫(kù)就好了,不多說(shuō)。
更多關(guān)于AES加密的內(nèi)容可以查AES加密
重點(diǎn)看看c函數(shù),RSA加密,這也是我最初學(xué)習(xí)的時(shí)候疑惑的一個(gè)點(diǎn),網(wǎng)上的文章都有一個(gè)逆序明文的操作,當(dāng)時(shí)并沒(méi)有弄明白。要搞清楚,關(guān)鍵在encryptstring方法。改寫(xiě)得好看了一點(diǎn),函數(shù)邏輯沒(méi)有變化
function encryptedString(a, b) {/* 取明文的ascii碼到c數(shù)組 */for (var f, g, h, i, j, k, l, c = [], d = b.length, e = 0; d > e;) {c[e] = b.charCodeAt(e);e++;}/* 補(bǔ)0到a.chunkSize,經(jīng)調(diào)試,achunkSize為常量126 */for (; 0 !== c.length % a.chunkSize;) {c[e++] = 0;}/* 外層for循環(huán)其實(shí)只會(huì)被執(zhí)行一次 */for (f = c.length, g = "", e = 0; f > e; e += a.chunkSize) {/* 大整數(shù) */for (j = new BigInt, h = 0, i = e; i < e + a.chunkSize; ++h) {j.digits[h] = c[i++];j.digits[h] += c[i++] << 8;}k = a.barrett.powMod(j, a.e);l = 16 === a.radix ? biToHex(k) : biToString(k, a.radix);g += l + " ";}return g.substring(0, g.length - 1) }舉例說(shuō)明一下這里的BigInt(只針對(duì)網(wǎng)易云JS),digits數(shù)組元素為16位的int型,相當(dāng)于每個(gè)元素可以表示16位二進(jìn)制數(shù),逆序拼接(元素為0的不拼入)成一個(gè)二進(jìn)制數(shù)即為實(shí)際表示的大整數(shù),說(shuō)逆序只是為了好理解,實(shí)際過(guò)程用偽代碼表示應(yīng)該是
ret = 0 for i in range(len(digits)):ret += digits[i] << (16 * i)如大整數(shù)digits數(shù)組為[1, 1, 0, 0]表示實(shí)際的二進(jìn)制數(shù)0000_0000_0000_0001_0000_0000_0000_0001
十六進(jìn)制的字符串"10001"表示成二進(jìn)制數(shù)就是0001_0000_0000_0000_0001,在表示成BigInt就是digits[1, 1],即十進(jìn)制的65537
同樣的,十六進(jìn)制串"596934344e6d",表示成BigInt為[5969(十六進(jìn)制), 3434,(十六進(jìn)制), 4e6d(十六進(jìn)制)]
接下來(lái)看看encryptedstring函數(shù)中將隨機(jī)字符串例如轉(zhuǎn)換成大整數(shù),以"Yi44Nm"為例,步驟如下
但是在Python中,都是按照正常順序處理的,這就是為什么我們需要將隨機(jī)串逆序了,理論上來(lái)說(shuō),"10001"也是要逆序的,不過(guò)這是個(gè)回文串,也就無(wú)所謂了。
import binasciis = "Yi44Nm"[::-1] # 6d4e34346959 hex_str = binascii.hexlify(s.encode()).decode() int(hex_str, 16)網(wǎng)上的文章幾乎都是一句倒序操作,就沒(méi)了下文了。
關(guān)于登錄的二維碼
想完成網(wǎng)易云二維碼登錄功能來(lái)著,像平常一樣直接抓包,結(jié)果怎么找也沒(méi)找著二維碼圖片在哪,之前碰到的二維碼真的就是一張圖片,網(wǎng)易云是JS在Canvas上繪制出來(lái)的。這樣我們沒(méi)法通過(guò)請(qǐng)求去獲取這張二維碼。
這里直接記錄一下解決辦法
附上chromediver的參數(shù)配置列表
總結(jié)
- 上一篇: QBXT 2018春季DP图论班 201
- 下一篇: 项目管理IPD产品开发