1. 程式人生 > >android 基礎 加密 加密類Cipher

android 基礎 加密 加密類Cipher

Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
//初始化為加密模式
cipher.init(Cipher.ENCRYPT_MODE, secretKey); // 設定工作模式為加密模式,出入金鑰(secretKey
Cipher用來完成加密操作。
cipher的doFinal()方法用來對資料進行加密
獲得一個私鈅加密類Cipher,DESede是演算法,ECB是加密模式,PKCS5Padding是填充方式
PKCS7Padding是缺幾個位元組就補幾個位元組的0,而PKCS5Padding是缺幾個位元組就補充幾個位元組的幾,好比缺6個位元組,就補充6個位元組的6

我們知道採用DES加密演算法的檔案,有可能會被人相對容易破解掉,並不是很安全,如果採用多次混合加密方式那麼就會增加被破解難度。

 * 3DES即三重DES加密演算法,也被稱為DESede或者Triple DES。使用三(或兩)個不同的金鑰對資料塊進行三次(或兩次)DES加密(加密一次要比進行普通加密的三次要快)。  * 三重DES的強度大約和112-bit的金鑰強度相當。通過迭代次數的提高了安全性,但同時也造成了加密效率低的問題。   

3DES屬於對稱加密  *金鑰長度:112位/168位  *工作模式:ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128  *填充方式:Nopadding/PKCS5Padding/ISO10126Padding/

PKCS7Padding跟PKCS5Padding的區別就在於資料填充方式,PKCS7Padding是缺幾個位元組就補幾個位元組的0,而PKCS5Padding是缺幾個位元組就補充幾個位元組的幾,好比缺6個位元組,就補充6個位元組的6

這裡需要注意一個問題,在建立Cipher物件是需要一個第三方Provider來提供演算法實現,在標準JDK中只是規定了JCE(JCE (Java Cryptography Extension) 是一組包,它們提供用於加密、金鑰生成和協商以及 Message Authentication Code(MAC)演算法的框架和實現。它提供對對稱、不對稱、塊和流密碼的加密支援,它還支援安全流和密封的物件。)介面,但是內部實現需要自己或者第三方提供。

網際網路的軟體設計一定少不了加密演算法,並且大量使用的都會是對稱加密,比較常見的對稱加密有:DES、3DES、RC4、AES等等;

加密演算法都有幾個共同的要點:

  1. 金鑰長度;(關係到金鑰的強度)
  2. 加密模式;(ecb、cbc等等)
  3. 塊加密演算法裡的填充方式區分;

對於加密模式,很多同學還不清楚,比如DES,也會有ECB、CBC等不同的區分,它們都是標準的;

     Windows加密庫中,預設則是CBC模式,也可以手工設定;

     Openssl庫要更明顯一點,它的函式名裡面就寫明瞭,比如:DES_ncbc_encrypt,一看就知道是cbc模式;

     JAVA裡面也比較清楚:Cipher c = Cipher.getInstance(”DES/CBC/PKCS5Padding”); 也可以看到是CBC模式

各種加密模式有什麼不同呢:(為了方便,這裡的加密key都取64位)

電子密碼本模式ECB:

最古老,最簡單的模式,將加密的資料分成若干組,每組的大小跟加密金鑰長度相同

然後每組都用相同的金鑰加密, 比如DES演算法, 如果最後一個分組長度不夠64位,要補齊64位;

定義:

          Enc(X,Y)是加密函式

          Dec(X,Y)是解密函式

          Key是加密金鑰;

          Pi ( i = 0,1…n)是明文塊,大小為64bit;

          Ci ( i = 0,1…n)是密文塊,大小為64bit;

ECB加密演算法可表示為:

           Ci = Enc(Key, Pi)

ECB解密演算法可以表示為:

          Pi = Dec(Key,Ci)

     演算法 特點:

  • 每次Key、明文、密文的長度都必須是64位;
  • 資料塊重複排序不需要檢測;
  • 相同的明文塊(使用相同的金鑰)產生相同的密文塊,容易遭受字典攻擊
  • 一個錯誤僅僅會對一個密文塊產生影響;

加密塊鏈模式CBC:

     與ECB模式最大的不同是加入了初始向量

     定義:

           Enc(X,Y)是加密函式

           Dec(X,Y)是解密函式

           Key是加密金鑰;

           Pi ( i = 0,1…n)是明文塊,大小為64bit;

           Ci ( i = 0,1…n)是密文塊,大小為64bit;

           XOR(X,Y)是異或運算;

           IV是初始向量(一般為64位);

    ECB加密演算法可表示為:

          C0 = Enc(Key, XOR(IV, P0)

            Ci = Enc(Key, XOR(Ci-1, Pi)

    ECB解密演算法可以表示為:

           P0 = XOR(IV, Dec(Key, C0))

            Pi = XOR(Ci-1, Dec(Key,Ci))

演算法特點:

  • 每次加密的密文長度為64位(8個位元組);
  • 當相同的明文使用相同的金鑰和初始向量的時候CBC模式總是產生相同的密文;
  • 密文塊要依賴以前的操作結果,所以,密文塊不能進行重新排列;
  • 可以使用不同的初始化向量來避免相同的明文產生相同的密文,一定程度上抵抗字典攻擊;
  • 一個錯誤發生以後,當前和以後的密文都會被影響;

加密反饋模式CFB:

加密反饋模式克服了需要等待8個位元組才能加密的缺點,它採用了分組密碼作為流密碼的金鑰流生成器;

     定義:

           Enc(X,Y)是加密函式

           Dec(X,Y)是解密函式

          Key是加密金鑰;

           Pi ( i = 0,1…n)是明文塊,大小為64bit;

           Ci ( i = 0,1…n)是密文塊,大小為64bit;

            Si ( i = 0,1…n),大小為8bit,n個連續的Si組成加密位移暫存器,一般n=8;

           Oi = Enc(Key, Si);

           Lef(x) 為取資料x的最左8個bit位;

           A(x,y)為合併x左移8位,空位用y填充

     CFB加密演算法可表示為:

           S0 = IV;

           Oi = Enc(Key, Si);

            Ci = XOR( Ci, Lef(Oi));

           Si = A(Si-1, Ci);

     CFB解密演算法可表示為:

           S0 = IV;

           Oi = Enc(Key, Si);

           Ci = XOR( Ci, Lef(Oi));

           Si = A(Si-1, Ci);

     圖示:

        

    特點:

  • 每次加密的Pi和Ci不大於64位;
  • 加密演算法和解密演算法相同,不能適用於公鑰演算法;
  • 使用相同的金鑰和初始向量的時候,相同明文使用CFB模式加密輸出相同的密文;
  • 可以使用不同的初始化變數使相同的明文產生不同的密文,防止字典攻擊;
  • 加密強度依賴於金鑰長度;
  • 加密塊長度過小時,會增加迴圈的數量,導致開銷增加;
  • 加密塊長度應時8位的整數倍(即位元組為單位);
  • 一旦某位資料出錯,會影響目前和其後8個塊的資料;

輸出反饋模式OFB:

與CFB模式不同之處在於, 加密位移暫存器與密文無關了,僅與加密key和加密演算法有關;

做法是不再把密文輸入到加密移位暫存器,而是把輸出的分組密文(Oi)輸入到一位暫存器;

     定義:

           Enc(X,Y)是加密函式

           Dec(X,Y)是解密函式

           Key是加密金鑰;

           Pi ( i = 0,1…n)是明文塊,大小為64bit;

           Ci ( i = 0,1…n)是密文塊,大小為64bit;

           Si ( i = 0,1…n),大小為8bit,n個連續的Si組成加密位移暫存器,一般n=8;

           Oi = Enc(Key, Si);

           Lef(x) 為取資料x的最左8個bit位;

           A(x,y)為合併x左移8位,空位用y填充

    CFB加密演算法可表示為:

           S0 = IV;

           Oi = Enc(Key, Si);

           Ci = XOR( Ci, Lef(Oi));

           Si = A(Si-1, Oi);          注意這裡與CFB模式的不同

    CFB解密演算法可表示為:

           S0 = IV;

           Oi = Enc(Key, Si);

           Ci = XOR( Ci, Lef(Oi));

           Si = A(Si-1, Oi);

    特點:

  • 與CFB類似,以下都是不同之處;
  • 因為密文沒有參與鏈操作,所以使得OFB模式更容易受到攻擊
  • 不會進行錯誤傳播,某位密文發生錯誤,只會影響該位對應的明文,而不會影響別的位;
  • 不是自同步的,如果加密和解密兩個操作失去同步,那麼系統需要重新初始化;
  • 每次重新同步時,應使用不同的初始向量。可以避免產生相同的位元流,避免”已知明文”攻擊 ;

Windows API進行加密引數設定:

     CryptGetKeyParam可以對HCRYPTKEY物件的各種引數進行查詢,包括加密模式、padding方式等;但這個函式不能用於查詢加密key的明文;

     但如果需要看到真正加密的key是什麼,則需要另外的API:CryptExportKey,選擇PLAINTEXTKEYBLOB方式進行匯出可以得到key的明文;

使用加密要注意的地方:

    當兩個封裝好的加密演算法對8byte資料進行DES加密時,如果加密出來的結果是一樣的,千萬不要認為這兩個演算法可以互換

     因為ECB模式,和向量全為0的CBC模式得到的密文前8byte,確實是一樣,但後面的密文就不一樣了;

使用加密以前確定你理解了它;

網際網路程式中加密模式的使用:

     ECB是不推薦的方式,Key相同時,相同的明文在不同的時候產生相同的明文,容易遭到字典攻擊;

     CBC由於加入了向量引數,一定程度上抵禦了字典工具,但缺點也隨之而來,一旦中間一個數據出錯或丟失,後面的資料將受到影響;

     CFB與CBC類似,好處是明文和密文不用是8bit的整數倍,中間一個數據出錯,隻影響後面的幾個塊的資料;

     OFB比CFB方式,一旦一個數據出錯,不會影響後面的資料,但安全性降低;

     因此,推薦使用CFB方式,但每個資料包單獨加密,否則一個數據包丟失,需要做很多容錯處理;

     當然,具體問題也要具體分析,對於只需要”特定安全性”①,不需要”計算安全性”以上的軟體,也可以使用ECB模式;