作者:厦禾Jimmy_218 | 来源:互联网 | 2023-09-17 14:22
DES是一个基于56位密钥的对称的加密算法,就是两边的密钥需要一致,在此就不考虑为什么不用安全性更高的AES或者采用非对称加密方法,比如RSA等等;关于密钥空间小,可以使用DES的派生算法3DE
DES是一个基于56位密钥的对称的加密算法,就是两边的密钥需要一致,在此就不考虑为什么不用安全性更高的AES或者采用非对称加密方法,比如RSA等等;关于密钥空间小,可以使用DES的派生算法3DES来进行加密。DES算法是把64位的明文输入块变成64位的密文输出块,所以这里需要BASE64编解码工具类,加密需要3个参数(Key、Data、Mode) Mode是加密还是解密。
public static String encryptDES(String encryptString, String encryptKey)
throws Exception {
//返回实现指定转换的 Cipher 对象 “算法/模式/填充”
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
//创建一个 DESKeySpec 对象,使用 8 个字节的key作为 DES 密钥的密钥内容。
DESKeySpec desKeySpec = new DESKeySpec(encryptKey.getBytes("UTF-8"));
//返回转换指定算法的秘密密钥的 SecretKeyFactory 对象。
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
//根据提供的密钥生成 SecretKey 对象。
SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
//使用 iv 中的字节作为 IV 来构造一个 IvParameterSpec 对象。复制该缓冲区的内容来防止后续修改。
IvParameterSpec iv = new IvParameterSpec(encryptKey.getBytes());
//用密钥和一组算法参数初始化此 Cipher;Cipher:加密、解密、密钥包装或密钥解包,具体取决于 opmode 的值。
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
//加密同时解码成字符串返回
return new String(BASE64.encode(cipher.doFinal(encryptString
.getBytes("UTF-8"))));
}
public static String decryptDES(String decodeString, String decodeKey) throws Exception {
//使用指定密钥构造IV
IvParameterSpec iv = new IvParameterSpec(decodeKey.getBytes());
//根据给定的字节数组和指定算法构造一个密钥。
SecretKeySpec skeySpec = new SecretKeySpec(decodeKey.getBytes(), "DES");
//返回实现指定转换的 Cipher 对象
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
//解密初始化
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
//解码返回
byte[] byteMi = BASE64.decode(decodeString.toCharArray());
byte decryptedData[] = cipher.doFinal(byteMi);
return new String(decryptedData);
}
}
几个错误需要解释下:
java.security.InvalidAlgorithmParameterException: IV must be 8 bytes long.
java.security.InvalidKeyException: key too short
这两种错误都是key的长度造成的,但官方说密钥是56位长度,这个有点不太明白,但你只要记住key的长度必须是8位!这个地方还请高手赐教!
IV向量:主要作用就是防止篡改的,这个地方如果不一致会导致数据的头部解出来是乱码,而后面正常。
BASE64 编解码工具类
public class BASE64 {
static public char[] encode(byte[] data) {
char[] out = new char[((data.length + 2) / 3) * 4];
for (int i = 0, index = 0; i >= 6;
out[index + 2] = alphabet[(trip ? (val & 0x3F) : 64)];
val >>= 6;
out[index + 1] = alphabet[val & 0x3F];
val >>= 6;
out[index + 0] = alphabet[val & 0x3F];
}
return out;
}
static public byte[] decode(char[] data) {
int len = ((data.length + 3) / 4) * 3;
if (data.length > 0 && data[data.length - 1] == '=')
--len;
if (data.length > 1 && data[data.length - 2] == '=')
--len;
byte[] out = new byte[len];
int shift = 0;
int accum = 0;
int index = 0;
for (int ix = 0; ix = 0) {
accum <<= 6;
shift += 6;
accum |= value;
if (shift >= 8) {
shift -= 8;
out[index++] = (byte) ((accum >> shift) & 0xff);
}
}
}
if (index != out.length)
throw new Error("miscalculated data length!");
return out;
}
static private char[] alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="
.toCharArray();
static private byte[] codes = new byte[256];
static {
for (int i = 0; i <256; i++)
codes[i] = -1;
for (int i = 'A'; i <= 'Z'; i++)
codes[i] = (byte) (i - 'A');
for (int i = 'a'; i <= 'z'; i++)
codes[i] = (byte) (26 + i - 'a');
for (int i = '0'; i <= '9'; i++)
codes[i] = (byte) (52 + i - '0');
codes['+'] = 62;
codes['/'] = 63;
}
}