之前我們介紹了《「後端」加密算法之 HMAC 算法》,今天我們認識 DES 算法。
從今天開始我們介紹加密算法中的對稱加密算法。相信大家看了前幾篇文章,已經對摘要算法的使用已經有了比較深的認識,摘要算法由于其算法特性,隻能單向加密,無法對資料反向解密,這時對稱加密算法就出現了。對稱算法主要有 DES、3DES 和 AES,今天我們重點介紹一下對稱加密算法中的 DES 算法。
DES 算法介紹
DES (Data Encryption Standard) 算法是世界上最常用的加密算法。在很長時間内,許多人心目中“密碼生成”與DES一直是個同義詞。盡管後來有個叫 Electronic Frontier Foundation的組織造了台價值 22 萬的機器嘗試破解 DES 加密的資料,直到現在 DES 和它的變種 3DES(三重資料加密算法)仍然在政府和銀行中被廣泛使用。
注:在 2001 年A ES 算法成為了 DES 算法的替代品。
國家标準局催生了 DES
1973 年 5 月,在尼克松任期,美國國家标準局下發了紅頭檔案,征求加密算法來保護傳輸過程中的資料。國家标準局等了很久一直沒有人投标,一直到 1974 年 8 月 6 日,尼克松卸任前三天,IBM 才拿出了自己家開發的一套代号 LUCIFER(金星)的東西。美國安全局評估後,在 1977 年 7 月 15 日采用了 LUCIFER 的一個變種作為資料加密标準 DES。
DES 很快被非數字媒體采用,比如電話線中的信号加密。在那些年裡,國際香料組織 IFF 曾用 DES 來加密那些用電話線傳輸的秘密配方。("With Data Encryption, Scents Are Safe at IFF," Computerworld 14, No. 21, 95 (1980))
同時,作為政府之後第二大急需加密的銀行業也将 DES 作為廣泛應用的标準,美國國家标準協會 ANSI 制定了整個銀行業的加密規範。1980 年采用的 ANSI X3.92 指定了 DES 算法的應用。
DES 算法特點
- DES 加密算法屬于對稱加密,加密與解密用的是同一個密鑰。
- DES 加密算法要求密鑰必須是 8 個位元組,即 64bit 長度;有效秘鑰長度為 56 位,每個位元組第 8 位用作奇偶校驗。
- 因為密鑰是 byte[8],代表字元串也可以是非可見的位元組,可以與 Base64 編碼算法一起使用。
- 加密、解密都需要通過位元組數組作為資料和密鑰進行處理。
- DES 算法是兩種加密技術的組合:混亂和擴散。先替代後置換。
- 易于實作,DES 算法隻是使用了标準的算術和邏輯運算,其作用的數最多也隻有 64 位,是以用 70 年代末期的硬體技術很容易實作。
DES 算法的優缺點
優點:
- 效率高,算法簡單,系統開銷小
- 适合加密大量資料
- 明文長度和密文長度相等
缺點:
- 需要以安全方式進行秘鑰交換
- 秘鑰管理複雜
DES 算法具有很高的安全性,到目前為止,除了用窮舉搜尋法對 DES 算法進行攻擊外,還沒有發現更有效的辦法。而 56 位長的密鑰的窮舉空間為 256,這意味着如果一台計算機的速度是每一秒種檢測一百萬個密鑰,則它搜尋完全部密鑰就需要将近 2285 年的時間,可見,這是難以實作的,當然,随著科學技術的發展,當出現超高速計算機後,我們可考慮把DES 密鑰的長度再增長一些,以此來達到更高的保密程度。
DES 加密原理
DES 使用一個 56 位的密鑰以及附加的 8 位奇偶校驗位,産生最大 64 位的分組大小。這是一個疊代的分組密碼,使用稱為 Feistel 的技術,其中将加密的文本塊分成兩半。使用子密鑰對其中一半應用循環功能,然後将輸出與另一半進行"異或"運算;接着交換這兩半,這一過程會繼續下去,但最後一個循環不交換。DES 使用 16 個循環,使用異或,置換,代換,移位操作四種基本運算。
DES 的加密過程
- 64 位密鑰經子密鑰産生算法産生出 16 個 48 位子密鑰:K1,K2,...,K16,分别供第 1 次,第 2 次,...,第 16 次加密疊代使用。
- 64 位明文首先經過初始置換 IP,将資料打亂重新排列并分成左右兩半,左邊 32 位構成L0,右邊 32 位構成 R0。
- 第 i 次加密疊代:由輪函數f實作子密鑰 Ki 對 Ri-1 的加密,結果為 32 位的資料組 f ( Ri-1 , Ki )。f ( Ri-1 , Ki ) 再與 Li-1 模 2 相加,又得到一個 32 位的資料組 Li-1 ⊕ f ( Ri-1 , Ki )。以 Li ⊕ f ( Ri-1 , Ki ) 作為下一次加密疊代的 Ri,以 Ri-1 作為下一次加密疊代的 Li ( i = 1,2,...,16)。
- 按照上一步的規則進行 16 次加密疊代。
- 第 16 次加密疊代結束後,以R 16 為左,L16 為右,合并産生一個 64 位的資料組。再經過逆初始置換I P-1,将資料重新排列,便得到 64 位密文。
DES 的解密過程
- 64 位密鑰經子密鑰産生算法産生出 16 個 48 位子密鑰:K1,K2,...,K16,分别供第 1 次,第 2 次,...,第 16 次解密疊代使用。
- 64 位密文首先經過初始置換 IP,将資料打亂重新排列并分成左右兩半,左邊 32 位構成R16,右邊 32 位構成 L16。
- 第 17-i 次解密疊代:由輪函數 f 實作子密鑰 Ki 對 Li 的解密,結果為 32 位的資料組 f ( Li , Ki )。f ( Li , Ki ) 再與 Ri 模 2 相加,又得到一個 32 位的資料組 Ri ⊕ f ( Li , Ki )。以 Ri ⊕ f ( Li , Ki ) 作為下一次解密疊代的 Li-1,以 Li 作為下一次解密疊代的 Li-1 ( i = 16,15,...,1)。
- 按照上一步的規則進行 16 次解密疊代。
- 第 16 次解密疊代結束後,以 L0 為左,R0 為右,合并産生一個 64 位的資料組。再經過逆初始置換 IP-1,将資料重新排列,便得到 64 位明文。
DES 算法實作
對稱加密算法會有不同的分組模式和填充方式,這裡我們使用的分組模式是 ECB,填充模式為 NoPadding,目前這種方式是比較常見的應用場景,實作代碼示例如下:
private static final String DES_ALGORITHM = "DES";
private static final String DES_CIPHER = "DES/ECB/NoPadding";
// des 加密
public static byte[] encryptDES(String data, String key) throws Exception {
// 生成SecretKey對象
SecretKey secretKey = desKeyGenerator(key);
// Cipher對象實際完成加密操作
Cipher cipher = Cipher.getInstance(DES_CIPHER);
// 用密匙初始化Cipher對象
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// 執行加密操作
return cipher.doFinal(data.getBytes());
}
// des 解密
public static byte[] decryptDES(byte[] data, String key) throws Exception {
// 生成SecretKey對象
SecretKey secretKey = desKeyGenerator(key);
// Cipher對象實際完成解密操作
Cipher cipher = Cipher.getInstance(DES_CIPHER);
// 用密匙初始化Cipher對象
cipher.init(Cipher.DECRYPT_MODE, secretKey);
// 執行解密操作
return cipher.doFinal(data);
}
/**
* DES Key 生成方法
*
* @param key
* @return
*/
private static SecretKey desKeyGenerator(String key) {
try {
// 建立一個DESKeySpec對象
DESKeySpec desKey = new DESKeySpec(key.getBytes());
// 建立一個密匙工廠
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
// 将DESKeySpec對象轉換成SecretKey對象
return keyFactory.generateSecret(desKey);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
return null;
}
/**
* Nopadding填充時,明文不是8位的倍數時需補足,這裡補位0x00
*
* @param b
* @return
*/
private static byte[] fillZero(byte[] b) {
int len = b.length;
//data不足8位以0補足8位
if (b.length % 8 != 0) {
len = b.length - b.length % 8 + 8;
} else {
return b;
}
byte[] needData = null;
needData = new byte[len];
for (int i = 0; i < len; i++) {
needData[i] = 0x00;
}
System.arraycopy(b, 0, needData, 0, b.length);
return needData;
}
應用場景
DES 算法最常用的場景是銀行業,如銀行卡收單,信用卡持卡人的 PIN 的加密傳輸,IC 卡 與 POS 間的雙向認證、金融交易資料包的 MAC 校驗等,均用到 DES 算法。另外,在 POS、ATM、磁卡及智能卡(IC 卡)、加油站、高速公路收費站等領域,DES 算法也被廣泛應用,以此來實作關鍵資料的保密。
總結
上面介紹了一下 DES 算法的和 DES 的實作,3DES 算法是 DES 的變種,并不是一種新的算法,這裡就不做過多介紹了,實作方式可以去下載下傳完整源碼檢視。關于對稱加密算法我們還沒有完整的讨論對稱加密中的分組模式以及填充模式,雖然代碼實作中也涉及了分組和填充,下一節我們會詳細介紹這部分内容。
DES 算法雖然有被破解的可能,但是目前依然在一些金融系統中被廣泛使用,尤其工作是在金融方面的小夥伴們,也是需要大家去了解和掌握的,以便于工作中遇到時可以有的放矢。
文章來源:https://zhuanlan.zhihu.com/p/345835990