详解DES加密算法及在Java程序中的使用示例
DES加密算法
DES全称为DataEncryptionStandard,即数据加密标准,是一种使用密钥加密的块算法,1976年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开来。
DES算法的入口参数有三个:Key、Data、Mode。其中Key为7个字节共56位,是DES算法的工作密钥;Data为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是56位,其算法主要分为两步:
1)初始置换
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。
其置换规则见下表:
58,50,42,34,26,18,10,2,60,52,44,36,28,20,12,4, 62,54,46,38,30,22,14,6,64,56,48,40,32,24,16,8, 57,49,41,33,25,17,9,1,59,51,43,35,27,19,11,3, 61,53,45,37,29,21,13,5,63,55,47,39,31,23,15,7,
2)逆置换
经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出。
此算法是对称加密算法体系中的代表,在计算机网络系统中广泛使用.
Java基本实现
packagecom.stone.security; importjava.security.Key; importjava.security.SecureRandom; importjavax.crypto.Cipher; importjavax.crypto.KeyGenerator; importjavax.crypto.SecretKey; importjavax.crypto.SecretKeyFactory; importjavax.crypto.spec.DESKeySpec; importjavax.crypto.spec.IvParameterSpec; /** *DES算法1972美国IBM研制,对称加密算法 */ publicclassDES{ //算法名称 publicstaticfinalStringKEY_ALGORITHM="DES"; //算法名称/加密模式/填充方式 publicstaticfinalStringCIPHER_ALGORITHM_ECB="DES/ECB/PKCS5Padding"; publicstaticfinalStringCIPHER_ALGORITHM_CBC="DES/CBC/PKCS5Padding"; publicstaticvoidmain(String[]args)throwsException{ /* *使用ECBmode *密钥生成器生成密钥 *ECBmodecannotuseIV */ byte[]key=generateKey(); byte[]encrypt=encrypt("胃炎F#*(x)".getBytes(),key); System.out.println(newString(decrypt(encrypt,key))); /* *使用CBCmode *使用密钥工厂生成密钥,加密解密 *iv:DESinCBCmodeandRSAcipherswithOAEPencodingoperation. */ DESKeySpecdks=newDESKeySpec(generateKey()); SecretKeyFactoryfactory=SecretKeyFactory.getInstance(KEY_ALGORITHM); SecretKeysecretKey=factory.generateSecret(dks); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM_CBC); cipher.init(Cipher.ENCRYPT_MODE,secretKey,newIvParameterSpec(getIV())); byte[]enc=cipher.doFinal("胃炎A%F#*(x)".getBytes());//加密 cipher.init(Cipher.DECRYPT_MODE,secretKey,newIvParameterSpec(getIV())); byte[]dec=cipher.doFinal(enc);//解密 System.out.println(newString(dec)); } staticbyte[]getIV(){ Stringiv="asdfivh7";//IVlength:mustbe8byteslong returniv.getBytes(); } /** *生成密钥 * *@return *@throwsException */ privatestaticbyte[]generateKey()throwsException{ KeyGeneratorkeyGenerator=KeyGenerator.getInstance(KEY_ALGORITHM); keyGenerator.init(56);//des必须是56,此初始方法不必须调用 SecretKeysecretKey=keyGenerator.generateKey(); returnsecretKey.getEncoded(); } /** *还原密钥 * *@paramkey *@return *@throwsException */ privatestaticKeytoKey(byte[]key)throwsException{ DESKeySpecdes=newDESKeySpec(key); SecretKeyFactorykeyFactory=SecretKeyFactory.getInstance(KEY_ALGORITHM); SecretKeysecretKey=keyFactory.generateSecret(des); returnsecretKey; } /** *加密 *@paramdata原文 *@paramkey *@return密文 *@throwsException */ publicstaticbyte[]encrypt(byte[]data,byte[]key)throwsException{ Keyk=toKey(key); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM_ECB); cipher.init(Cipher.ENCRYPT_MODE,k,newSecureRandom()); returncipher.doFinal(data); } /** *解密 *@paramdata密文 *@paramkey *@return明文、原文 *@throwsException */ publicstaticbyte[]decrypt(byte[]data,byte[]key)throwsException{ Keyk=toKey(key); Ciphercipher=Cipher.getInstance(CIPHER_ALGORITHM_ECB); cipher.init(Cipher.DECRYPT_MODE,k,newSecureRandom()); returncipher.doFinal(data); } }
Java三重DES实现:
packagecom.stone.security; importjavax.crypto.Cipher; importjavax.crypto.KeyGenerator; importjavax.crypto.SecretKey; importjavax.crypto.SecretKeyFactory; importjavax.crypto.spec.DESedeKeySpec; importjavax.crypto.spec.IvParameterSpec; /** *三重加密3DES也作TripleDES, */ publicclassTripleDES{ //算法名称 publicstaticfinalStringKEY_ALGORITHM="DESede"; //算法名称/加密模式/填充方式 publicstaticfinalStringCIPHER_ALGORITHM_ECB="DESede/ECB/PKCS5Padding"; publicstaticfinalStringCIPHER_ALGORITHM_CBC="DESede/CBC/PKCS5Padding"; privateKeyGeneratorkeyGen; privateSecretKeysecretKey; privateSecretKeysecretKey2; privateCiphercipher; privatestaticbyte[]encryptData; publicstaticvoidmain(String[]args)throwsException{ TripleDEStripleDES=newTripleDES("ECB"); tripleDES.encrypt("sau8jzxlcvm,'123`98(*^&%^^JCBZX>>A<S<}}{"); System.out.println("加密后:"+newString(encryptData)); System.out.println("解密后:"+newString(tripleDES.decrypt(encryptData))); tripleDES=newTripleDES("CBC"); tripleDES.encrypt2("sau8jzxlcDQV#><«|vm,'123`98(*^&%^^JCBZX>>A<S<}}{"); System.out.println("加密后:"+newString(encryptData)); System.out.println("解密后:"+newString(tripleDES.decrypt2(encryptData))); } publicTripleDES(Stringmode)throwsException{ if("ECB".equals(mode)){ //cipher=Cipher.getInstance(KEY_ALGORITHM); cipher=Cipher.getInstance(CIPHER_ALGORITHM_ECB); keyGen=KeyGenerator.getInstance(KEY_ALGORITHM); secretKey=keyGen.generateKey(); }elseif("CBC".equals(mode)){ cipher=Cipher.getInstance(CIPHER_ALGORITHM_CBC); keyGen=KeyGenerator.getInstance(KEY_ALGORITHM); DESedeKeySpecspec=newDESedeKeySpec(keyGen.generateKey().getEncoded()); secretKey2=SecretKeyFactory.getInstance(KEY_ALGORITHM).generateSecret(spec); } } /** *加密 *@paramstr *@return *@throwsException */ publicbyte[]encrypt(Stringstr)throwsException{ cipher.init(Cipher.ENCRYPT_MODE,secretKey); returnencryptData=cipher.doFinal(str.getBytes()); } /** *解密 *@paramencrypt *@return *@throwsException */ publicbyte[]decrypt(byte[]encrypt)throwsException{ cipher.init(Cipher.DECRYPT_MODE,secretKey); returnencryptData=cipher.doFinal(encrypt); } byte[]getIV(){ return"administ".getBytes(); } /** *加密 *@paramstr *@return *@throwsException */ publicbyte[]encrypt2(Stringstr)throwsException{ cipher.init(Cipher.ENCRYPT_MODE,secretKey2,newIvParameterSpec(getIV())); returnencryptData=cipher.doFinal(str.getBytes()); } /** *解密 *@paramencrypt *@return *@throwsException */ publicbyte[]decrypt2(byte[]encrypt)throwsException{ cipher.init(Cipher.DECRYPT_MODE,secretKey2,newIvParameterSpec(getIV())); returnencryptData=cipher.doFinal(encrypt); } }