DMM破解原理之HLS篇(一)

前些時間在dmm上面買了部影片,發現雖然提供了在線和下載兩種方式觀看,但是由於兩種方式都有一定的保護措施,所以需要先解密文件才能在實現任意播放。於是花點時間簡單研究了下兩種方式的加密原理:

(1)在線播放(HLS)

這種方案是採用後端FFMPEG切片+AES加密的進行推流,然後前端根據m3u文件採用HTML5+BLOB的方式進行播放。

(2)下載播放 (SLDRM)

這種方案是採用Silverlight+Playready的方案的來對視頻文件進行保護。

由於時間關係只簡單看了下第一種,直接貼下隨手寫的完整的解還原密代碼吧:

#coding: utf8
import sys,os
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import math

AES_KEY='63CB93E75E251B61CA28A095FFCE6EB6'

class dmmDecrypt():

    def __init__(self, key):
        self.key = key
        self.mode = AES.MODE_CBC
     
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode, self.key)
        plain_text = cryptor.decrypt(text)
        return plain_text.rstrip('\0')

def parse_hex(hex_str):
    l=int(math.ceil(len(hex_str)/2))
    buf=''
    for i in range(0,l):
        s=hex_str[(i*2):((i+1)*2)]
        buf=buf+chr(int(s,16))
    return buf
 
def joinfile(fromdir,filename,todir):
    if not os.path.exists(todir):
        os.mkdir(todir)
    if not os.path.exists(fromdir):
        print('Wrong directory')
    outfile = open(os.path.join(todir,filename),'wb')
    files = os.listdir(fromdir) #list all the part files in the directory
    count=0
    for file in files:
        if('media' in file):
            print file
            os.rename(file,file.split('_')[2]+'.enc')
    for file in files:
        if('.enc' in file):
            count+=1
            print('['+str(count)+']'+'Decrypting...')
            key= parse_hex(AES_KEY)
            dmm = dmmDecrypt(key) 
            e=open( file,'rb')
            d = dmm.decrypt(e.read())  
            s=open(file[:-4],'wb')
            s.write(d)       
            s.close()
            e.close()
            os.remove(file)
    print ('Decrypt all file successful ')     
    print count
    for i in range(0,count):
            filepath = os.path.join(fromdir,str(i)+'.ts')
            print('['+str(float(i)*100/float(count))+']'+'Rebuilding...')
            infile = open(filepath,'rb')
            data = infile.read()
            outfile.write(data)
            infile.close()
            os.remove(str(i)+'.ts')
    outfile.close()
    print ('Rebuild all file successful ')     
 
if __name__ == '__main__':
    filename = 'out.mp4'
    try:
        joinfile(sys.path[0],filename,sys.path[0])
    except:
        print('Error joining files:')
        print(sys.exc_info()[0],sys.exc_info()[1])
                      

至於第二種方式解密,安全防護上確實高了不少,簡單搜了下網上貌似對Playready資料討論的也不多,等有時間再填坑吧。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章