走在IT的路上 2013-11-07
desdesedejavaaes
接下来我们介绍对称加密算法,最常用的莫过于DES数据加密算法。
DES
DES-DataEncryptionStandard,即数据加密算法。是IBM公司于1975年研究成功并公开发表的。DES算法的入口参数有三个:Key、Data、Mode。其中Key为8个字节共64位,是DES算法的工作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密或解密。
DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位。
通过java代码实现如下:Coder类见Java加密技术(一)
Java代码收藏代码
importjava.security.Key;
importjava.security.SecureRandom;
importjavax.crypto.Cipher;
importjavax.crypto.KeyGenerator;
importjavax.crypto.SecretKey;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.DESKeySpec;
/**
*DES安全编码组件
*
*<pre>
*支持DES、DESede(TripleDES,就是3DES)、AES、Blowfish、RC2、RC4(ARCFOUR)
*DESkeysizemustbeequalto56
*DESede(TripleDES)keysizemustbeequalto112or168
*AESkeysizemustbeequalto128,192or256,but192and256bitsmaynotbeavailable
*Blowfishkeysizemustbemultipleof8,andcanonlyrangefrom32to448(inclusive)
*RC2keysizemustbebetween40and1024bits
*RC4(ARCFOUR)keysizemustbebetween40and1024bits
*具体内容需要关注JDKDocumenthttp://.../docs/technotes/guides/security/SunProviders.html
*</pre>
*
*@author梁栋
*@version1.0
*@since1.0
*/
publicabstractclassDESCoderextendsCoder{
/**
*ALGORITHM算法<br>
*可替换为以下任意一种算法,同时key值的size相应改变。
*
*<pre>
*DESkeysizemustbeequalto56
*DESede(TripleDES)keysizemustbeequalto112or168
*AESkeysizemustbeequalto128,192or256,but192and256bitsmaynotbeavailable
*Blowfishkeysizemustbemultipleof8,andcanonlyrangefrom32to448(inclusive)
*RC2keysizemustbebetween40and1024bits
*RC4(ARCFOUR)keysizemustbebetween40and1024bits
*</pre>
*
*在KeytoKey(byte[]key)方法中使用下述代码
*<code>SecretKeysecretKey=newSecretKeySpec(key,ALGORITHM);</code>替换
*<code>
*DESKeySpecdks=newDESKeySpec(key);
*SecretKeyFactorykeyFactory=SecretKeyFactory.getInstance(ALGORITHM);
*SecretKeysecretKey=keyFactory.generateSecret(dks);
*</code>
*/
publicstaticfinalStringALGORITHM="DES";
/**
*转换密钥<br>
*
*@paramkey
*@return
*@throwsException
*/
privatestaticKeytoKey(byte[]key)throwsException{
DESKeySpecdks=newDESKeySpec(key);
SecretKeyFactorykeyFactory=SecretKeyFactory.getInstance(ALGORITHM);
SecretKeysecretKey=keyFactory.generateSecret(dks);
//当使用其他对称加密算法时,如AES、Blowfish等算法时,用下述代码替换上述三行代码
//SecretKeysecretKey=newSecretKeySpec(key,ALGORITHM);
returnsecretKey;
}
/**
*解密
*
*@paramdata
*@paramkey
*@return
*@throwsException
*/
publicstaticbyte[]decrypt(byte[]data,Stringkey)throwsException{
Keyk=toKey(decryptBASE64(key));
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,k);
returncipher.doFinal(data);
}
/**
*加密
*
*@paramdata
*@paramkey
*@return
*@throwsException
*/
publicstaticbyte[]encrypt(byte[]data,Stringkey)throwsException{
Keyk=toKey(decryptBASE64(key));
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,k);
returncipher.doFinal(data);
}
/**
*生成密钥
*
*@return
*@throwsException
*/
publicstaticStringinitKey()throwsException{
returninitKey(null);
}
/**
*生成密钥
*
*@paramseed
*@return
*@throwsException
*/
publicstaticStringinitKey(Stringseed)throwsException{
SecureRandomsecureRandom=null;
if(seed!=null){
secureRandom=newSecureRandom(decryptBASE64(seed));
}else{
secureRandom=newSecureRandom();
}
KeyGeneratorkg=KeyGenerator.getInstance(ALGORITHM);
kg.init(secureRandom);
SecretKeysecretKey=kg.generateKey();
returnencryptBASE64(secretKey.getEncoded());
}
}
延续上一个类的实现,我们通过MD5以及SHA对字符串加密生成密钥,这是比较常见的密钥生成方式。
再给出一个测试类:
Java代码收藏代码
importstaticorg.junit.Assert.*;
importorg.junit.Test;
/**
*
*@author梁栋
*@version1.0
*@since1.0
*/
publicclassDESCoderTest{
@Test
publicvoidtest()throwsException{
StringinputStr="DES";
Stringkey=DESCoder.initKey();
System.err.println("原文:\t"+inputStr);
System.err.println("密钥:\t"+key);
byte[]inputData=inputStr.getBytes();
inputData=DESCoder.encrypt(inputData,key);
System.err.println("加密后:\t"+DESCoder.encryptBASE64(inputData));
byte[]outputData=DESCoder.decrypt(inputData,key);
StringoutputStr=newString(outputData);
System.err.println("解密后:\t"+outputStr);
assertEquals(inputStr,outputStr);
}
}
得到的输出内容如下:
Console代码收藏代码
原文:DES
密钥:f3wEtRrV6q0=
加密后:C6qe9oNIzRY=
解密后:DES
由控制台得到的输出,我们能够比对加密、解密后结果一致。这是一种简单的加密解密方式,只有一个密钥。
其实DES有很多同胞兄弟,如DESede(TripleDES)、AES、Blowfish、RC2、RC4(ARCFOUR)。这里就不过多阐述了,大同小异,只要换掉ALGORITHM换成对应的值,同时做一个代码替换SecretKeysecretKey=newSecretKeySpec(key,ALGORITHM);就可以了,此外就是密钥长度不同了。
Java代码收藏代码
/**
*DESkeysizemustbeequalto56
*DESede(TripleDES)keysizemustbeequalto112or168
*AESkeysizemustbeequalto128,192or256,but192and256bitsmaynotbeavailable
*Blowfishkeysizemustbemultipleof8,andcanonlyrangefrom32to448(inclusive)
*RC2keysizemustbebetween40and1024bits
*RC4(ARCFOUR)keysizemustbebetween40and1024bits
**/