前些時間在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資料討論的也不多,等有時間再填坑吧。