天天看點

DRM标準學習筆記2-ForwardLock原理及實作

1. ForwardLock

  • ForwardLock 是DRM1.0中最簡單的一種傳輸方式。請參考DRM标準學習筆記1

2. ForwardLock工作流程

  1. 用特定工具,或者是手動編寫,将一個普通的視訊檔案(例如mp4) 生成一個符合标準的DRM檔案,放到伺服器上;
  2. 使用者付費後,用下載下傳工具将此DRM檔案下載下傳到本地;
  3. 下載下傳工具必須支援這種DRM檔案,下載下傳的時候,其内部實際上是把此DRM檔案進行了加密,加密算法可以采用AES等算法。密鑰應該是每台機器生成一個唯一的密鑰,加密和解密密鑰是相同的。
  4. 這樣,在本地端就有了一個加密的媒體檔案,使用者可以在本機上進行播放,但如果COPY到另外的機器上,由于密鑰不同,是以不以成功解密,這樣就達到了ForwardLock的目的。

3. 符合ForwardLocak标準的DRM檔案格式

  • 如下所示的格式:
    --boundary12345\r\n
        Content-type: video/mp4\r\n
        Content-Transfer-Encoding: binary\r\n
        \r\n
          .
          .
          .\r\n
        --boundary12345--\r\n
          
  • 說明:
    • DRM檔案格式其實就是在原始的媒體檔案加了一個頭和一個尾。如上所示。
    • 頭一共增加了四行,在這裡我把隐藏字元也用轉義字寫出來,目的就是為了看清楚。
    • 第一行是以--開頭,後跟一個随機的字元串,但結尾時也必須是這個字元串。然後是回車換行。
    • 第二行是說明此檔案的mime type是什麼
    • 第三行說的是編碼格式,是二進制,還是64 base。
    • 第四行是一個空行。
    • 然後是原始的媒體檔案,這裡用三個點的三行來進行表示。
    • 最後,在原始檔案的末尾先來一個回車換行
    • 最後一行是以--開頭和結尾,中間放上跟頭一樣的字元串,回車換行。

4. Android中如何實作ForwardLocak?

  • 最後,目前的Android代碼(Android4.1JB)是支援此功能的,即通過Browser下載下傳的時候,如果是FrowardLocak檔案則會進行檔案的加密。
  • 如果想自己寫一個來玩玩,可以用以下的代碼實作:
    mDrmManagerClient = new DrmManagerClient();
        mConvertSessionID = mDrmManagerClient->openConvertSession(s_imetype);
    
        ...
    
        DrmBuffer buffer((char *)data, (int)size);
        DrmConvertedStatus *convertedStatus =
               mDrmManagerClient->convertData(mConvertSessionID, &buffer);
    
        int write_len = writeConvertedStatusToFile(convertedStatus, mDrmOffset + offset);
    
        ...
    
        // close drm session and write drm file size.
        convertedStatus = mDrmManagerClient->closeConvertSession(mConvertSessionID);
        writeConvertedStatusToFile(convertedStatus);
    
        // delete the instance.
        delete mDrmManagerClient;
        mDrmManagerClient=NULL;
          
  • 說明:
    • writeConvertedStatusToFile是我寫的一個處理轉換結果的私有函數,主要是把結果convertedStatus中的資料進行儲存。
    • 在最後,關閉ConvertSession後,還會傳回一個convertedStatus,這裡邊也包含資料,并且多包含了一個offset,位置正好位于頭部,這裡存的是整個檔案的大小,因為大小隻有在整個轉換完成,關閉時才會知道。
    • 另外,如果想對一個普通的媒體檔案進行加密,則需要自己加上DRM的頭和尾然後用此類的執行個體進行轉換。

5. Android中DRM代碼結構分析

  • 代碼位置
    • frameworks/base/drm/ (DRM的Java和JNI代碼)
      • java/
      • jni/
    • frameworks/av/drm/ (DRM的Native層代碼,包括引擎和服務)
      • common/
      • drmserver/
      • libdrmframework/
        • DrmManagerClient.cpp
        • include/
        • plugins/
    • frameworks/base/media/ (此路徑中有關DRM的代碼可能是遺留代碼,目前還不知道有什麼用)
      • libdrm/mobile1/
      • java/drm/