前言
默认的jdk不支持DESeee的算法,本地化的JDK中配置有拦截规则,可以通过使用bouncycastle的jar包中的DESEngine类来进行DESeee算法的运算。
DES的8字节加解密
DESEngine可以进行8字节数据的加解密,具体的调用方法如下:
byte[] key = ByteUtil.fromHex("0102030405060708");
byte[] input = ByteUtil.fromHex("0102030405060708");
byte[] out = new byte[8];
// 使用DESEngine进行加密
DESEngine desEngine = new DESEngine();
desEngine.init(true, new KeyParameter(key));
desEngine.processBlock(input, 0, out, 0);
System.out.println("des encrypt=" + ByteUtil.toHex(out));
// 使用DESEngine进行解密
desEngine.init(false, new KeyParameter(key));
desEngine.processBlock(input, 0, out, 0);
System.out.println("des decrypt=" + ByteUtil.toHex(out));
输出结果:
des encrypt=77a7d6bcf57962b9
des decrypt=187a9fccd218a4dd
3DES的8字节加解密
DESede
bouncycastle本身支持DES的ede运算,使用org.bouncycastle.crypto.engines.DESedeEngine
可以进行DES的ede运算,这个类的代码很简单,就是调用DESEngine的方法进行了"加密-解密-加密"的操作,调用示例代码:
byte[] key = ByteUtil.fromHex("010203040506070801020304050607080102030405060708");
byte[] input = ByteUtil.fromHex("0102030405060708");
byte[] out = new byte[input.length];
DESedeEngine desEdeEngine = new DESedeEngine();
// 使用DESedeEngine进行加密
desEdeEngine.init(true, new KeyParameter(key));
desEdeEngine.processBlock(input, 0, out, 0);
System.out.println("des ede encrypt=" + ByteUtil.toHex(out));
// 使用DESedeEngine进行解密
desEdeEngine.init(false, new KeyParameter(key));
desEdeEngine.processBlock(input, 0, out, 0);
System.out.println("des ede decrypt=" + ByteUtil.toHex(out));
输出结果:
des ede encrypt=77a7d6bcf57962b9
des ede decrypt=187a9fccd218a4dd
DESeee
bouncycastle中没有提供DESeee的实现代码,但是我们可以根据DESedeEngine的代码自己实现一个DESeeeEngine,只要将processBlock中"加解加"的代码"加加加"即可,具体代码参见:https://github.com/itlgl/cryptoutil
调用示例代码:
byte[] key = ByteUtil.fromHex("010203040506070801020304050607080102030405060708");
byte[] input = ByteUtil.fromHex("0102030405060708");
byte[] out = new byte[input.length];
DESeeeEngine desEeeEngine = new DESeeeEngine();
// 使用DESeeeEngine进行加密
desEeeEngine.init(true, new KeyParameter(key));
desEeeEngine.processBlock(input, 0, out, 0);
System.out.println("des eee encrypt=" + ByteUtil.toHex(out));
// 使用DESeeeEngine进行解密
desEeeEngine.init(false, new KeyParameter(key));
desEeeEngine.processBlock(input, 0, out, 0);
System.out.println("des eee decrypt=" + ByteUtil.toHex(out));
输出结果:
des eee encrypt=ee5e6222f17509cd
des eee decrypt=5e207f47b1ea8ee2
des和3des的ECB、CBC
bouncycastle中的BlockCIpher是可以嵌套的,使用org.bouncycastle.crypto.modes.CBCBlockCipher
嵌套DESEngine可以实现DES的cbc单位字节加密功能。org.bouncycastle.crypto.BufferedBlockCipher
可以嵌套BlockCipher的实现,进行8字节整数倍字节的加解密运算。
那么,3des EEE CBC的代码可以这样写:
public static byte[] desEeeCbc(final byte[] key, final byte[] src, final byte[] icv, final boolean encrypting) throws DesException {
if(key == null || (key.length != 16 && key.length != 24)) {
throw new DesException("DesEEE key should be 16 or 24 bytes");
}
if(icv == null || icv.length != 8) {
throw new DesException("DesEEE icv should be 8 bytes");
}
if(src == null || src.length == 0) {
throw new DesException("DesEEE src should not be empty");
}
if(src.length % 8 != 0) {
throw new DesException("DesEEE src length should be be an integer multiple of 8");
}
byte[] result = new byte[src.length];
try {
BufferedBlockCipher engine = new BufferedBlockCipher(new CBCBlockCipher(new DESeeeEngine()));
engine.init(encrypting, new ParametersWithIV(new KeyParameter(key), icv));
int len = engine.processBytes(src, 0, src.length, result, 0);
engine.doFinal(result, len);
} catch (InvalidCipherTextException e) {
throw new DesException(e);
}
return result;
}
总结
1、使用DESEngine可以实现DES的8字节数据的加密和解密
2、使用DESedeEngine可以实现3des ede的8字节数据的加密和解密
3、使用BufferedBlockCipher嵌套DESedeEngine可以实现des ede ecb模式的加解密
4、bouncycastle中还有CCMBlockCipher、CFBBlockCipher等,可以组合实现多种3des的加解密方式
完整的代码:https://github.com/itlgl/cryptoutil
参考:
[1] 3DES 和 ECB CBC 加密方式