一提到對稱加密,你們首先想到的可能就是DES(Data Encryption Standard)技術了.DES技術是一種將64比特的明文加密成64比特的密文的對稱密碼算法,所以理論上來說,他的密鑰長度也是64位,但由於在DES的密鑰中每隔7比特,就會設置一個用於錯誤檢查的比特,因此實際上DES的密鑰的長度只有56比特.php
DES是以64比特的明文(比特序列)爲一個單位進行加密,這64比特的單位成爲分組,通常來講,以分組爲單位進行處理的密碼算法成爲分組密碼.所以它只能加密64比特的數據,對於長度超過64比特的明文,就須要對DES加密進行迭代.DES加密和解密的過程以下圖所示:
java
由於DES的基本結構是由Horst Feistel設計的,因此DES的基本結構也被稱爲Feistel網絡.在Feistel網絡中,加密的各個步驟稱爲輪,整個加密過程就是進行若干次輪的循環.DES就是一種16輪循環的Feistel網絡.
算法
上面的圖表示出了Feistel網絡中一輪的計算流程.經過上面的圖咱們能夠知道,在這一過程當中起到關鍵做用的就是輪函數:他根據歐策和子密鑰生成對」左側」進行加密的比特序列.而後輪函數的輸出與左側進行XOR運算,獲得了左側的加密結果,過程梳理以下:安全
可是,咱們根據圖也能發現,這樣雖然左側通過加密了,但右側並無通過加密.因此Feistel網絡須要進行第二次的輪加密,而且須要將左側和右側進行對調.通常來講DES加密是須要三次輪加密的,而且這一過程是可逆的,只要子密鑰不變,就可以從密文推導出明文.這也就是Feistel網絡的解密操做原理.咱們如今來總結一下Feistel網絡的一些性質:網絡
如今咱們附上一段DES加密算法在Java中的實現:dom
package org.shangzeng.cipher; import javax.crypto.*; import javax.crypto.spec.DESKeySpec; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.spec.InvalidKeySpecException; public class DESTest { public static void main(String[] args) { String greeting="HelloWorld"; String key="shangzeng"; try { byte[] encryptArray=DESTest.encryptDES(greeting.getBytes(),key.getBytes()); System.out.println(greeting+"加密後的結果爲:"+new String(encryptArray)); byte[] decryptArray=DESTest.decryptDES(encryptArray,key.getBytes()); System.out.println(greeting+"解密後的結果爲:"+new String(decryptArray)); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (InvalidKeySpecException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } } //DES算法要有一個隨機數源,由於Random是根據時間戳生成的有限隨機數,比較容易破解,因此在這裏使用SecureRandom private static SecureRandom secureRandom=new SecureRandom(); private static SecretKey getSecretKey(byte[] keyArray) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException { DESKeySpec desKeySpec=new DESKeySpec(keyArray); //建立DES密鑰工廠 SecretKeyFactory keyFactory=SecretKeyFactory.getInstance("DES"); //用密鑰工廠將DESKeySpec轉換成密鑰key SecretKey secretKey=keyFactory.generateSecret(desKeySpec); return secretKey; } public static byte[] encryptDES(byte[] contentArray,byte[] keyArray) throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, BadPaddingException, IllegalBlockSizeException { return des(contentArray,keyArray,Cipher.ENCRYPT_MODE); } public static byte[] decryptDES(byte[] encryptArray,byte[] keyArray) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException { return des(encryptArray,keyArray,Cipher.DECRYPT_MODE); } private static byte[] des(byte[] contentArray,byte[] keyArray,int mode) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException { SecretKey secretKey=getSecretKey(keyArray); //獲取真正執行加/解密操做的Cipher Cipher cipher=Cipher.getInstance("DES"); //執行加/解密操做 cipher.init(mode,secretKey,secureRandom); byte[] result=cipher.doFinal(contentArray); return result; } }
講到這裏,必需要提一下,差分分析和線性分析.函數
差分分析是一種針對分組密碼的分析方法,他的思路是」改變一部分明文並分析密文如何隨之改變」.理論上來講,明文只要改變,哪怕是一個比特的改變,密文的比特排列也應該完全的改變.所以只要經過分析密文改變中所產生的誤差,就能夠得到破譯密碼的線索.學習
線性分析是由鬆井充提出的,他的思路是:」將明文和密文的一些對應比特進行XOR並計算其結果爲零的機率」,若是密文具有足夠的隨機性,則任選一些明文和密文的對應比特進行XOR結果爲零的機率爲1/2.若是可以找到大幅偏離1/2的部分,則能夠藉此得到一些與密鑰有關的信息.若是使用線性分析,對於DES只須要2^47組明文和密文就可以完成破解.相比須要嘗試2^56個密鑰的暴力破解來講,所需的計算量大幅減小.加密
密碼破譯者能夠選擇任意明文並得到其加密的結果,這是差分分析和線性分析的一個大前提.這種攻擊方式也被稱爲 選擇明文攻擊(CPA,Chosen Plaintext Attack)spa
DES從1977年開始被美國聯邦信息處理標準(FIPS)採用,主要被用於國家政府和銀行等行業,但在1999年1月,distributed.net與電子前哨基金會合做,在22小時15分鐘內即公開破解了一個DES密鑰,另有一些分析報告提出了該算法的理論上的弱點。在2001年,DES做爲一個標準已經被所取代。另外,DES已經再也不做爲美國國家標準科技協會(前國家標準局)的一個標準.
若是說DES不安全,那麼咱們該用什麼加密算法呢?期待下次分享
《詳細解析DES系列加密技術(二)》
若是你們有什麼建議或問題,歡迎你們進羣討論,另羣裏有學習資料奉送哦
羣號爲: 661594029