Java密码学(3)——对称加密算法
对称加密算法的加***和解***相同,用**对原数据加密得到密文,对密文解密密得到明文,解密算法是加密算法的逆运算。
DES是最具代表性的对称加密算法,DESede是DES算法的变种又称3DES。DES算法有ecb和cbc两种模式。 AES算法作为DES的替代,更安全,性能更好。
- DES算法
模型图如下
这里采用单DES的ECB模式用代码实现
/**
* DES ECB模式加解密
* @param key
* @param data
* @param mode 0-加密,1-解密
* @return
*/
public static String desecb(String key, String data, int mode) {
try {
DESKeySpec dks = new DESKeySpec(Hex.decodeHex(key.toCharArray()));
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey secretKey = keyFactory.generateSecret(dks);
Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
if(mode==0){
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
}else{
cipher.init(Cipher.DECRYPT_MODE, secretKey);
}
return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data.toCharArray())));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (DecoderException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return null;
}
测试代码
String key = "404142434445464748494a4b4c4d4e4f";
String data = "404142434445464748494a4b4c4d4e4f";
String encode = desecb(key, data, 1);
System.out.println("DES加密后的密文:"+encode);
String decode = desecb(key, encode, 0);
System.out.println("DES解密后的明文:"+decode);
运行结果
DES加密后的密文:f2db549c724485f5eff4e2f84fd31835
DES解密后的明文:404142434445464748494a4b4c4d4e4f
注意:DES算法中key和data必须为8字节整数倍的HexString
- PBE算法
PBE——Password Based Encryption,基于口令加密。
DES算法**长度是16字节,3DES**长度是32字节,不方便记忆。PBE算法用口令替代**,口令方便记忆。比如我们登录windows操作系统就要输入一个口令。
PBE算法可以看成是消息摘要算法+对称加密算法。我们需要一个口令和盐,盐是一个随机信息。通过消息摘要算法,对口令+盐生成**,该**用于对称加密。
模型如下
PBEWITHMD5andDES模式的PBE算法实现代码
/**
* 基于口令加密PBE算法
* @param password 口令
* @param data 数据
* @param salt 盐
* @param mode
* 0-加密,1-解密
* @return
*/
public static String pbe(String password, String data, byte[] salt, int mode){
try {
//转换密码
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBEWITHMD5andDES");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
PBEParameterSpec paramSpec = new PBEParameterSpec(salt, 100);
Cipher cipher = Cipher.getInstance("PBEWITHMD5andDES");
if (mode == 0) {
cipher.init(Cipher.ENCRYPT_MODE, secretKey, paramSpec);
} else {
cipher.init(Cipher.DECRYPT_MODE, secretKey, paramSpec);
}
return Hex.encodeHexString(cipher.doFinal(Hex.decodeHex(data
.toCharArray())));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (DecoderException e) {
e.printStackTrace();
}
return null;
}
测试代码
String password = "yel";
System.out.println("口令:"+password);
String data = "404142434445464748494a4b4c4d4e4f";
System.out.println("原始数据:"+data);
byte[] salt = new SecureRandom().generateSeed(8);
System.out.println("盐:"+Hex.encodeHexString(salt));
String encode = pbe(password, data, salt, 0);
System.out.println("PBE加密后的密文:" + encode);
String decode = pbe(password, encode, salt, 1);
System.out.println("PBE解密后的明文:" + decode);
运行结果
口令:yel
原始数据:404142434445464748494a4b4c4d4e4f
盐:d6bae74f476d8f6f
PBE加密后的密文:290fae52e24e874146ca2dad8986876cc117730f09ec46ac
PBE解密后的明文:404142434445464748494a4b4c4d4e4f