前面的仅仅是做了编码或者摘要,下面看看真正的加密技术。
DES
public classDESUtil {static final String ALGORITHM = "DES";/*** 生成文本格式的DES Key
*@return*@throwsException*/
public static String getKey() throwsException{
KeyGenerator generator=KeyGenerator.getInstance(ALGORITHM);
generator.init(new SecureRandom());//加盐
returnBase64Util.encode(generator.generateKey().getEncoded());
}/*** 从文本 格式DES Key转换成SecretKey对象
*@paramkey
*@return
*/
public static SecretKey parseKeyFromString(String key)throwsException{
DESKeySpec desKeySpec= newDESKeySpec(Base64Util.decode(key));
SecretKeyFactory factory=SecretKeyFactory.getInstance(ALGORITHM);
SecretKey secretKey=factory.generateSecret(desKeySpec);returnsecretKey;
}/*** DES 加密
*@paramdata
*@paramkey
*@return*@throwsException*/
public static String encrypt(String data,String key)throwsException{
SecretKey secretKey=parseKeyFromString(key);
Cipher cipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] bytes = cipher.doFinal(data.getBytes("UTF-8"));returnBase64Util.encode(bytes);
}/*** DES 解密
*@paramdata
*@paramkey
*@return*@throwsException*/
public static String decrypt(String data,String key)throwsException{
SecretKey secretKey=parseKeyFromString(key);
Cipher cipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] bytes =cipher.doFinal(Base64Util.decode(data));return new String(bytes,"UTF-8");
}public static void main(String[] args)throwsException {
String str= "Hello,DES";
String key=getKey();
System.out.println("原文:" +str);
System.out.println("密钥:" +key);
String encryptedStr=encrypt(str, key);
System.out.println("加密后:" +encryptedStr);
String decryptedStr=decrypt(encryptedStr, key);
System.out.println("解密后:" +decryptedStr);
}
}
类似DESKeySpec,Java中很多*KeySpec的类都实现了KeySpec的空接口,Java只关心某个类是否是一种Key的实现,至于具体如何实现的是具体加密解密算法要关心的。
再次看到Base64的身影,由此可以看出,Base64其实充当着字符串和byte数组之间的转换器,真实的的密钥数据其实是byte类型的,但是在阅读和传输过程中字符串比较方便,所以我们能看到的很多密钥信息其实都是Base64编码。
Ciper为密文工具类,它是一个很高级的抽象类,有很多种Cipher的实现,可以通过Cipher.getInstance()方法获取到。
getInstance方法接收的算法名称非常多:
测试:
原文:Hello,DES
密钥:8ePQx0m1I4k=加密后:bM06WR8OIL2sQOB8SUSXRA==解密后:Hello,DES
AES
AES是DES的升级版,解决了DES的很多不足,上述DES代码改成AES的改动很小:
static final String ALGORITHM = "AES";/*** 从文本 格式AES Key转换成SecretKey对象
*@paramkey
*@return
*/
public static SecretKey parseKeyFromString(String key)throwsException{
SecretKey secretKey= newSecretKeySpec(Base64Util.decode(key), ALGORITHM);returnsecretKey;
}
PBE
PBE与DES、AES同属对称加密,不同之处在于其密钥可以由用户管理,即密钥可以不用通过KeyGenerator来生成,可以是任意字符。为了增强安全性,PBE强制必须要有参数(java.security.spec.AlgorithmParameterSpec),可以理解为强制加盐,否则将报错。
public classPBEUtil {static final String ALGORITHM = "PBEWITHMD5andDES";private static SecretKey parseKeyFromString(String key) throwsException{
PBEKeySpec pbeKey= newPBEKeySpec(key.toCharArray());
SecretKeyFactory factory=SecretKeyFactory.getInstance(ALGORITHM);returnfactory.generateSecret(pbeKey);
}/*** PBE 加密
*@paramdata
*@paramkey
*@return*@throwsException*/
public static String encrypt(String data,String key,byte[] salt)throwsException{
SecretKey secretKey=parseKeyFromString(key);
Cipher cipher=Cipher.getInstance(ALGORITHM);
PBEParameterSpec params= new PBEParameterSpec(salt, 100);
cipher.init(Cipher.ENCRYPT_MODE, secretKey,params);byte[] bytes = cipher.doFinal(data.getBytes("UTF-8"));returnBase64Util.encode(bytes);
}/*** DES 解密
*@paramdata
*@paramkey
*@return*@throwsException*/
public static String decrypt(String data,String key,byte[] salt)throwsException{
SecretKey secretKey=parseKeyFromString(key);
Cipher cipher=Cipher.getInstance(ALGORITHM);
PBEParameterSpec params= new PBEParameterSpec(salt, 100);
cipher.init(Cipher.DECRYPT_MODE, secretKey,params);byte[] bytes =cipher.doFinal(Base64Util.decode(data));return new String(bytes,"UTF-8");
}public static void main(String[] args)throwsException {
String str= "Hello,PBE";
String key= "abc";byte[] salt = new byte[8];newRandom().nextBytes(salt);
System.out.println("原文:" +str);
System.out.println("密钥:" +key);
String encryptedStr=encrypt(str, key,salt);
System.out.println("加密后:" +encryptedStr);
String decryptedStr=decrypt(encryptedStr, key,salt);
System.out.println("解密后:" +decryptedStr);
}
}
参考资料: