DES加密
package com.paladin.common.util;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.security.Key;
/**
* Created with IntelliJ IDEA.
* Description:
* User: luckywcw
* Date: 2020-05-09
* Time: 11:22
*/
public class DESUtil {
public static final String KEY = "K8sSjzL9";
/**
* 加密
* @param secretKey,str
* @return
* @throws Exception
*/
public static String DES_CBC_Encrypt(String secretKey, String str) {
try {
byte[] keyBytes = secretKey.getBytes();
byte[] content = str.getBytes();
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, getKey(keyBytes));
byte[] result = cipher.doFinal(content);
return byteToHexString(result);
} catch (Exception e) {
System.out.println("exception:" + e.toString());
}
return null;
}
/**
* 解密
* @param secretKey,str
* @return
* @throws Exception
*/
public static String DES_CBC_Decrypt(String secretKey, String str) {
try {
byte[] keyBytes = secretKey.getBytes();
byte[] content = hexToByteArray(str);
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, getKey(keyBytes));
byte[] result = cipher.doFinal(content);
return new String(result, "utf-8");
} catch (Exception e) {
System.out.println("exception:" + e.toString());
}
return null;
}
public static Key getKey(byte[] key) throws Exception {
DESKeySpec dks = new DESKeySpec(key);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(dks);
return securekey;
}
/**
* 将byte数组转换为表示16进制值的字符串
* @param bytes
* @return
* @throws Exception
*/
private static String byteToHexString(byte[] bytes) {
StringBuilder sb = new StringBuilder(bytes.length);
String sTemp;
for (byte aByte : bytes) {
sTemp = Integer.toHexString(0xFF & aByte);
if (sTemp.length() < 2)
sb.append(0);
sb.append(sTemp.toUpperCase());
}
return sb.toString();
}
/**
* 将表示16进制值的字符串转换为byte数组
* @param inHex
* @return
* @throws Exception
*/
private static byte[] hexToByteArray(String inHex) {
int hexLen = inHex.length();
byte[] result;
if (hexLen % 2 == 1) {
hexLen++;
result = new byte[(hexLen / 2)];
inHex = "0" + inHex;
} else {
result = new byte[(hexLen / 2)];
}
int j = 0;
for (int i = 0; i < hexLen; i += 2) {
result[j] = (byte) Integer.parseInt(inHex.substring(i, i + 2), 16);
j++;
}
return result;
}
}
上面为正确代码。一开始是加密正常,解密报错
javax.crypto.BadPaddingException: Given final block not properly padded
这个错误,网上有很多解决方法:
1.生成KEY的时候不要用SecureRandom生成SecretKey,而是使用SecretKeyFactory
2.确保加密和解密使用的同一个KEY
但是我发现都符合上面的要求,但是还是报这个错,就去比较加密和解密的过程,发现先前解密代码中又这么一段:
DESKeySpec keySpec = new DESKeySpec(keyBytes);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey key = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(keyBytes));
导致了加密和解密的最后的key是不一样的
最后把加密和解密的生成key的方法统一,后面就没问题了。