目录
DES加密算法DES加密原理DES 加密算法Java实现
前面阿粉说了关于 MD5 加密算法,还有 RSA 加密算法的实现,以及他们的前世今生,今天阿粉在来说一下这个关于 DES 加密算法,又是怎么实现的。
DES加密算法
DES 加密,是对称加密,之前阿粉也已经说了这个对称加密和非对称加密都是代表了什么意思,对称加密,顾名思义,加密和解密的运算全都是使用的同样的秘钥。
DES加密算法原始思想可以参照二战德国的恩格玛机,其基本思想大致相同。传统的密码加密都是由古代的循环移位思想而来,恩格玛机在这个基础之上进行了扩散模糊。但是本质原理都是一样的。现代DES在二进制级别做着同样的事:替代模糊,增加分析的难度。
DES概述图
DES加密原理
DES 使用一个 56 位的密钥以及附加的 8 位奇偶校验位,产生最大 64 位的分组大小。
这是一个迭代的分组密码,使用称为 Feistel 的技术,其中将加密的文本块分成两半。
使用子密钥对其中一半应用循环功能,然后将输出与另一半进行“异或”运算;接着交换这两半,这一过程会继续下去,但最后一个循环不交换。
DES 使用 16 个循环,使用异或,置换,代换,移位操作四种基本运算。
虽然现在 DES 加密已经被破解,但是如果保密级别不是很高的话,依然是可以使用的。
既然我们已经知道DES 加密的过程是从明文64位开始,然后到初始置换IP,之后生成子秘钥,然后在秘钥控制下进行16轮加密转换,再做一次交换左右32比特,最后进行逆初始置换IP,最后返回密文的64位。
就像下面的图:
具体的算法,阿粉暂时不说,直接开始我们的 Java 代码实现。
DES 加密算法Java实现
publicclassDESUtil{ /** *偏移变量,固定占8位字节 */ privatefinalstaticStringIV_PARAMETER="12345678"; /** *密钥算法 */ privatestaticfinalStringALGORITHM="DES"; /** *加密/解密算法-工作模式-填充模式 */ privatestaticfinalStringCIPHER_ALGORITHM="DES/CBC/PKCS5Padding"; /** *默认编码 */ privatestaticfinalStringCHARSET="utf-8"; /** *生成key * *@parampassword *@return *@throwsException */ privatestaticKeygenerateKey(Stringpassword)throwsException{ DESKeySpecdks=newDESKeySpec(password.getBytes(CHARSET)); SecretKeyFactorykeyFactory=SecretKeyFactory.getInstance(ALGORITHM); returnkeyFactory.generateSecret(dks); } /** *DES加密字符串 * *@parampassword加密密码,长度不能够小于8位 *@paramdata待加密字符串 *@return加密后内容 */ publicstaticStringencrypt(Stringpassword,Stringdata){ if(password==null||password.length()<8){ thrownewRuntimeException("加密失败,key不能小于8位"); } if(data==null) returnnull; try{ KeysecretKey=generateKey(password); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM); IvParameterSpeciv=newIvParameterSpec(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 returnnewString(Base64.getEncoder().encode(bytes)); }catch(Exceptione){ e.printStackTrace(); returndata; } } /** *DES解密字符串 * *@parampassword解密密码,长度不能够小于8位 *@paramdata待解密字符串 *@return解密后内容 */ publicstaticStringdecrypt(Stringpassword,Stringdata){ if(password==null||password.length()<8){ thrownewRuntimeException("加密失败,key不能小于8位"); } if(data==null) returnnull; try{ KeysecretKey=generateKey(password); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM); IvParameterSpeciv=newIvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); cipher.init(Cipher.DECRYPT_MODE,secretKey,iv); returnnewString(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))),CHARSET); }catch(Exceptione){ e.printStackTrace(); returndata; } } /** *DES加密文件 * *@paramsrcFile待加密的文件 *@paramdestFile加密后存放的文件路径 *@return加密后的文件路径 */ publicstaticStringencryptFile(Stringpassword,StringsrcFile,StringdestFile){ if(password==null||password.length()<8){ thrownewRuntimeException("加密失败,key不能小于8位"); } try{ IvParameterSpeciv=newIvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE,generateKey(key),iv); InputStreamis=newFileInputStream(srcFile); OutputStreamout=newFileOutputStream(destFile); CipherInputStreamcis=newCipherInputStream(is,cipher); byte[]buffer=newbyte[1024]; intr; while((r=cis.read(buffer))>0){ out.write(buffer,0,r); } cis.close(); is.close(); out.close(); returndestFile; }catch(Exceptionex){ ex.printStackTrace(); } returnnull; } /** *DES解密文件 * *@paramsrcFile已加密的文件 *@paramdestFile解密后存放的文件路径 *@return解密后的文件路径 */ publicstaticStringdecryptFile(Stringpassword,StringsrcFile,StringdestFile){ if(password==null||password.length()<8){ thrownewRuntimeException("加密失败,key不能小于8位"); } try{ Filefile=newFile(destFile); if(!file.exists()){ file.getParentFile().mkdirs(); file.createNewFile(); } IvParameterSpeciv=newIvParameterSpec(IV_PARAMETER.getBytes(CHARSET)); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE,generateKey(key),iv); InputStreamis=newFileInputStream(srcFile); OutputStreamout=newFileOutputStream(destFile); CipherOutputStreamcos=newCipherOutputStream(out,cipher); byte[]buffer=newbyte[1024]; intr; while((r=is.read(buffer))>=0){ cos.write(buffer,0,r); } cos.close(); is.close(); out.close(); returndestFile; }catch(Exceptionex){ ex.printStackTrace(); } returnnull; } } 复制代码 其实 DES 加密过程如果要是简化出来的话,无非就是那么几步。
第一步:明文根据IP置换,变成新的明文,得到一个乱序的64 bit 明文组。
将新得到的加密明文分成两个部分,Lo和Ro。
第二步:子秘钥生成,DES加密过程有16轮循环函数,其中需要用到16个密钥,所以要将这56 bit密钥扩展生成16个48 bit 的子密钥。
第三步:得到16个子密钥K
第四步:S盒代换数据
第五步:P盒代换,P为固定置换,将经过S盒变换得到的32 bit进行一个置换操作。至此,得到F函数的最终输出。
第六步:循环16次
第七步:IP的逆置换
最后输出64位的比特密文。
就这么简单,如果你要是理解了的话,那就没那么多问题了。
到此这篇关于详解DES加密算法的原理与Java实现的文章就介绍到这了,更多相关Java DES加密算法内容请搜索中国红客联盟以前的文章或继续浏览下面的相关文章希望大家以后多多支持中国红客联盟!