最近因為工作需求又開始研究這個老議題 - - -DRM
原來業界真的會用到這個技術,而且不是特定企業、特定產品
只要產品跟版權扯上關係,Solution幾乎都會聽到這個名詞!
有關DRM的介紹:http://zh.wikipedia.org/wiki/%E6%95%B0%E5%AD%97%E7%89%88%E6%9D%83%E7%AE%A1%E7%90%86
很多人會認為DRM是一個標準有其規範,只要其中一個環節不符合規範,就不符合DRM。
但其實這都是無稽之談,不過大致應用都大同小異,還是那張老圖(差不多如此)。
DRM是一種機制、一種技術:這技術可以只是簡單的hash function或是AES加密技術,更複雜的話可以到AES或3DES + RSA的混合型,想更安全架個CA 再加上時戳或是想弄個組合型金鑰都可以,更甚至有些混合型結合Smart Card等中介元件 或是生物識別。只是越安全的系統,實作上有一定的難度之外,他還無法吸引消費者使用。
正題開始:
本實驗我們使用既定AES加密的Sample code,主要探討其中的可行跟教學。
在影片保護中我們無法針對整個影片做對稱式加密(考量效能問題),Android環境下超過五秒建議用thread或service完成,更會增加整個實作複雜度。
有鑑於此,我們用FileInputStream 讀取檔案存成byte,並只針對前端部分的byte作加密並組合成保護的檔案。
宣告變數:
public class MainActivity extends Activity implements SurfaceHolder.Callback {
//宣告 按鈕及影音播放相關元件.
private Button enc_btn;
private Button dec_btn;
private SurfaceView suf_view;
private SurfaceHolder suf_holder;
private String playpath="/sdcard/abc.3gp";
private MediaPlayer m_player = new MediaPlayer();
//宣告 AES加密相關資料.
private String key_value = "g7dohju42837lz9b";
private byte[] bytesKey = key_value.getBytes();
private AESAlgorithm alg = new AESAlgorithm(AESAlgorithm.KEY_SIZE_128);
private int[] wordsKeyExpansion = alg.createKeyExpansion(bytesKey);
private byte[] bytesPlaintext,bytesEncrypted;
//宣告 影片讀取byte_code之存放容器
private byte[] enc_plaintext,enc_head,enc_target;//第一段加密需要使用的 byte_code之宣告.
private byte[] dec_cipher,dec_head,dec_target;//第二段解密需要使用的 byte_code之宣告.
=======================
宣告按鈕及加密段
enc_btn = (Button)this.findViewById(R.id.encode);
dec_btn = (Button)this.findViewById(R.id.decode);
dec_btn.setEnabled(false);
suf_view = (SurfaceView)this.findViewById(R.id.sview);
suf_holder = suf_view.getHolder();
suf_holder.addCallback(this);
suf_holder.setFixedSize(176, 144);
suf_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
enc_btn.setOnClickListener(new OnClickListener(){
public void onClick(View view){
FileInputStream fi = null;
FileOutputStream fo = null;
try {
fi = new FileInputStream(playpath);
BufferedInputStream bfin = new BufferedInputStream(fi);
int fileSize = fi.available();
enc_plaintext = new byte[fileSize];
enc_head = new byte[128];
bfin.read(enc_plaintext,0,fileSize);
//載入前 128byte並加密
System.arraycopy(enc_plaintext, 0, enc_head, 0, 128);
bytesPlaintext = enc_head;
bytesEncrypted = alg.cipher(bytesPlaintext,wordsKeyExpansion);
System.out.println("byresEncrypted.length:"+bytesEncrypted.length);//印出後發現加密後的檔頭長度從128變為144
//合併檔案到 enc_target
enc_target = new byte[bytesEncrypted.length + fileSize-128];
System.arraycopy(bytesEncrypted,0, enc_target, 0, bytesEncrypted.length);
System.arraycopy(enc_plaintext,128,enc_target,bytesEncrypted.length,fileSize-128);
//將加密的檔頭及後續 並覆蓋回存
File filetemp = new File(playpath);
fo = new FileOutputStream(filetemp);
fo.write(enc_target);
fo.close();
enc_btn.setEnabled(false);
dec_btn.setEnabled(true);
} catch (IOException e) {
e.printStackTrace();
}
}});
=======================
未完待續...
關於我 : Kun-hsien(KH)
研究&開發是一段艱難的旅程:享受在資料字串與信號間遊走。
從VB->HTML->PHP->MySQL->Fedora->MCSE->JAVA->XML->Android->Embeded C->C ->C# ->Python-> Arduino -> IoT ->MQTT ->Spark ->CAN ->I2C....
這裡除了紀錄開發Apps遇到問題的Solution並分享給大家外,各種開發技術的文章也在此探討!希望大家都能順利解決自己遇到的問題!
您好 Kun-hsien Lee大師,可以請教這有完整專案,還是現有專案可以給我參考一下媽>< 最近幾天都弄不出來...不好意思麻煩您了
回覆刪除