詳解DES加密算法的原理與Java實(shí)現(xiàn)
前面阿粉說了關(guān)于 MD5 加密算法,還有 RSA 加密算法的實(shí)現(xiàn),以及他們的前世今生,今天阿粉在來說一下這個關(guān)于 DES 加密算法,又是怎么實(shí)現(xiàn)的。
DES加密算法
DES 加密,是對稱加密,之前阿粉也已經(jīng)說了這個對稱加密和非對稱加密都是代表了什么意思,對稱加密,顧名思義,加密和解密的運(yùn)算全都是使用的同樣的秘鑰。
DES加密算法原始思想可以參照二戰(zhàn)德國的恩格瑪機(jī),其基本思想大致相同。傳統(tǒng)的密碼加密都是由古代的循環(huán)移位思想而來,恩格瑪機(jī)在這個基礎(chǔ)之上進(jìn)行了擴(kuò)散模糊。但是本質(zhì)原理都是一樣的?,F(xiàn)代DES在二進(jìn)制級別做著同樣的事:替代模糊,增加分析的難度。
DES概述圖
DES加密原理
DES 使用一個 56 位的密鑰以及附加的 8 位奇偶校驗(yàn)位,產(chǎn)生最大 64 位的分組大小。
這是一個迭代的分組密碼,使用稱為 Feistel 的技術(shù),其中將加密的文本塊分成兩半。
使用子密鑰對其中一半應(yīng)用循環(huán)功能,然后將輸出與另一半進(jìn)行“異或”運(yùn)算;接著交換這兩半,這一過程會繼續(xù)下去,但最后一個循環(huán)不交換。
DES 使用 16 個循環(huán),使用異或,置換,代換,移位操作四種基本運(yùn)算。
雖然現(xiàn)在 DES 加密已經(jīng)被破解,但是如果保密級別不是很高的話,依然是可以使用的。
既然我們已經(jīng)知道DES 加密的過程是從明文64位開始,然后到初始置換IP,之后生成子秘鑰,然后在秘鑰控制下進(jìn)行16輪加密轉(zhuǎn)換,再做一次交換左右32比特,最后進(jìn)行逆初始置換IP,最后返回密文的64位。
就像下面的圖:
具體的算法,阿粉暫時不說,直接開始我們的 Java 代碼實(shí)現(xiàn)。
DES 加密算法Java實(shí)現(xiàn)
public?class?DESUtil?{ ? ????/** ?????*?偏移變量,固定占8位字節(jié) ?????*/ ????private?final?static?String?IV_PARAMETER?=?"12345678"; ????/** ?????*?密鑰算法 ?????*/ ????private?static?final?String?ALGORITHM?=?"DES"; ????/** ?????*?加密/解密算法-工作模式-填充模式 ?????*/ ????private?static?final?String?CIPHER_ALGORITHM?=?"DES/CBC/PKCS5Padding"; ????/** ?????*?默認(rèn)編碼 ?????*/ ????private?static?final?String?CHARSET?=?"utf-8"; ? ????/** ?????*?生成key ?????* ?????*?@param?password ?????*?@return ?????*?@throws?Exception ?????*/ ????private?static?Key?generateKey(String?password)?throws?Exception?{ ????????DESKeySpec?dks?=?new?DESKeySpec(password.getBytes(CHARSET)); ????????SecretKeyFactory?keyFactory?=?SecretKeyFactory.getInstance(ALGORITHM); ????????return?keyFactory.generateSecret(dks); ????} ? ? ????/** ?????*?DES加密字符串 ?????* ?????*?@param?password?加密密碼,長度不能夠小于8位 ?????*?@param?data?待加密字符串 ?????*?@return?加密后內(nèi)容 ?????*/ ????public?static?String?encrypt(String?password,?String?data)?{ ????????if?(password==?null?||?password.length()?<?8)?{ ????????????throw?new?RuntimeException("加密失敗,key不能小于8位"); ????????} ????????if?(data?==?null) ????????????return?null; ????????try?{ ????????????Key?secretKey?=?generateKey(password); ????????????Cipher?cipher?=?Cipher.getInstance(CIPHER_ALGORITHM); ????????????IvParameterSpec?iv?=?new?IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); ????????????cipher.init(Cipher.ENCRYPT_MODE,?secretKey,?iv); ????????????byte[]?bytes?=?cipher.doFinal(data.getBytes(CHARSET)); ? ????????????//JDK1.8及以上可直接使用Base64,JDK1.7及以下可以使用BASE64Encoder ????????????//Android平臺可以使用android.util.Base64 ????????????return?new?String(Base64.getEncoder().encode(bytes)); ? ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace(); ????????????return?data; ????????} ????} ? ????/** ?????*?DES解密字符串 ?????* ?????*?@param?password?解密密碼,長度不能夠小于8位 ?????*?@param?data?待解密字符串 ?????*?@return?解密后內(nèi)容 ?????*/ ????public?static?String?decrypt(String?password,?String?data)?{ ????????if?(password==?null?||?password.length()?<?8)?{ ????????????throw?new?RuntimeException("加密失敗,key不能小于8位"); ????????} ????????if?(data?==?null) ????????????return?null; ????????try?{ ????????????Key?secretKey?=?generateKey(password); ????????????Cipher?cipher?=?Cipher.getInstance(CIPHER_ALGORITHM); ????????????IvParameterSpec?iv?=?new?IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); ????????????cipher.init(Cipher.DECRYPT_MODE,?secretKey,?iv); ????????????return?new?String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))),?CHARSET); ????????}?catch?(Exception?e)?{ ????????????e.printStackTrace(); ????????????return?data; ????????} ????} ? ????/** ?????*?DES加密文件 ?????* ?????*?@param?srcFile??待加密的文件 ?????*?@param?destFile?加密后存放的文件路徑 ?????*?@return?加密后的文件路徑 ?????*/ ????public?static?String?encryptFile(String?password,?String?srcFile,?String?destFile)?{ ? ????????if?(password==?null?||?password.length()?<?8)?{ ????????????throw?new?RuntimeException("加密失敗,key不能小于8位"); ????????} ????????try?{ ????????????IvParameterSpec?iv?=?new?IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); ????????????Cipher?cipher?=?Cipher.getInstance(CIPHER_ALGORITHM); ????????????cipher.init(Cipher.ENCRYPT_MODE,?generateKey(key),?iv); ????????????InputStream?is?=?new?FileInputStream(srcFile); ????????????OutputStream?out?=?new?FileOutputStream(destFile); ????????????CipherInputStream?cis?=?new?CipherInputStream(is,?cipher); ????????????byte[]?buffer?=?new?byte[1024]; ????????????int?r; ????????????while?((r?=?cis.read(buffer))?>?0)?{ ????????????????out.write(buffer,?0,?r); ????????????} ????????????cis.close(); ????????????is.close(); ????????????out.close(); ????????????return?destFile; ????????}?catch?(Exception?ex)?{ ????????????ex.printStackTrace(); ????????} ????????return?null; ????} ? ????/** ?????*?DES解密文件 ?????* ?????*?@param?srcFile??已加密的文件 ?????*?@param?destFile?解密后存放的文件路徑 ?????*?@return?解密后的文件路徑 ?????*/ ????public?static?String?decryptFile(String?password,?String?srcFile,?String?destFile)?{ ????????if?(password==?null?||?password.length()?<?8)?{ ????????????throw?new?RuntimeException("加密失敗,key不能小于8位"); ????????} ????????try?{ ????????????File?file?=?new?File(destFile); ????????????if?(!file.exists())?{ ????????????????file.getParentFile().mkdirs(); ????????????????file.createNewFile(); ????????????} ????????????IvParameterSpec?iv?=?new?IvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); ????????????Cipher?cipher?=?Cipher.getInstance(CIPHER_ALGORITHM); ????????????cipher.init(Cipher.DECRYPT_MODE,?generateKey(key),?iv); ????????????InputStream?is?=?new?FileInputStream(srcFile); ????????????OutputStream?out?=?new?FileOutputStream(destFile); ????????????CipherOutputStream?cos?=?new?CipherOutputStream(out,?cipher); ????????????byte[]?buffer?=?new?byte[1024]; ????????????int?r; ????????????while?((r?=?is.read(buffer))?>=?0)?{ ????????????????cos.write(buffer,?0,?r); ????????????} ????????????cos.close(); ????????????is.close(); ????????????out.close(); ????????????return?destFile; ????????}?catch?(Exception?ex)?{ ????????????ex.printStackTrace(); ????????} ????????return?null; ????} }
其實(shí) DES 加密過程如果要是簡化出來的話,無非就是那么幾步。
第一步:明文根據(jù)IP置換,變成新的明文,得到一個亂序的64 bit 明文組。
將新得到的加密明文分成兩個部分,Lo和Ro。
第二步:子秘鑰生成,DES加密過程有16輪循環(huán)函數(shù),其中需要用到16個密鑰,所以要將這56 bit密鑰擴(kuò)展生成16個48 bit 的子密鑰。
第三步:得到16個子密鑰K
第四步:S盒代換數(shù)據(jù)
第五步:P盒代換,P為固定置換,將經(jīng)過S盒變換得到的32 bit進(jìn)行一個置換操作。至此,得到F函數(shù)的最終輸出。
第六步:循環(huán)16次
第七步:IP的逆置換
最后輸出64位的比特密文。
就這么簡單,如果你要是理解了的話,那就沒那么多問題了。
到此這篇關(guān)于詳解DES加密算法的原理與Java實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Java DES加密算法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java類加載機(jī)制實(shí)現(xiàn)流程及原理詳解
這篇文章主要介紹了Java類加載機(jī)制實(shí)現(xiàn)流程及原理詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-06-06云IDE:Eclipse Che:Eclipse下一代IDE(推薦)
這篇文章主要介紹了云IDE:Eclipse Che:Eclipse下一代IDE,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09spring boot thymeleaf 圖片上傳web項目根目錄操作步驟
這篇文章主要介紹了spring boot thymeleaf 圖片上傳web項目根目錄步驟,本文給大家提到了thymeleaf的基礎(chǔ)知識,需要的朋友可以參考下2018-03-03Java中的對象、類、抽象類、接口、繼承之間的聯(lián)系
這篇文章主要介紹了Java中的對象、類、抽象類、接口、繼承之間的聯(lián)系,文章講解的很清晰,有不太懂的同學(xué)可以多研究下2021-02-02Mybatis plus實(shí)現(xiàn)Distinct去重功能
這篇文章主要介紹了Mybatis plus實(shí)現(xiàn)Distinct去重功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12