使用 java 通过 3DES-128 位 CBC 模式(填充零))解密数据
Decrypt a data by 3DES-128 bits CBC Mode (padding zero)) using java
在解密加密数据的过程中,我遇到了一些挑战。如果有人能帮助我度过难关,我会很高兴。
尽管如此,我已经研究了执行此操作的算法,因为我要从设备中获取数据,该设备已经具有其 Base Derivation Key(BDK) , 初始加载的密钥序列号和初始加载的密码输入设备密钥.
在提供的文档中,我们有初始加载密钥序列号、数据加密密钥变体和轨道 2 数据(明文形式)。
在这个例子中,我了解到他们实际上使用了 3DES-128 位 CBC 模式(填充零)方法。
我现在的问题是,明文是如何从加密数据中得到的。如果有人能帮我接通(说明解密这些数据的流程或算法),我将非常高兴。
非常感谢您的宝贵时间。
关于 Oracle 实现的更愚蠢的事情之一是 SecretKeyFactory
不支持 DES ABA 密钥,也称为 "two-key" DES 密钥。
这些用于三重 DES 操作的密钥由单个 DES 密钥 A 和后跟单个 DES 密钥 B 组成。密钥 A 用于 DES EDE 中的第一次和最后一次 DES 迭代(加密-解密-加密) .
如果您留在软件中,您可以创建一种创建此类密钥的方法。问题是生成的密钥实际上有 192 位,这根本不正确 - 它使得无法区分密钥大小。
无论如何,下面的代码可以用来生成DES ABA密钥:
private static final int DES_KEY_SIZE_BYTES = 64 / Byte.SIZE;
private static final int DES_ABA_KEY_SIZE_BYTES = 2 * DES_KEY_SIZE_BYTES;
private static final int DES_ABC_KEY_SIZE_BYTES = 3 * DES_KEY_SIZE_BYTES;
public static SecretKey createDES_ABAKey(byte[] key) {
if (key.length != DES_ABA_KEY_SIZE_BYTES) {
throw new IllegalArgumentException("128 bit key argument with size expected (including parity bits.)");
}
try {
byte[] desABCKey = new byte[DES_ABC_KEY_SIZE_BYTES];
System.arraycopy(key, 0, desABCKey, 0, DES_ABA_KEY_SIZE_BYTES);
System.arraycopy(key, 0, desABCKey, DES_ABA_KEY_SIZE_BYTES, DES_KEY_SIZE_BYTES);
SecretKeySpec spec = new SecretKeySpec(desABCKey, "DESede");
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey desKey = factory.generateSecret(spec);
return desKey;
} catch (GeneralSecurityException e) {
throw new RuntimeException("DES-EDE ABC key factory not functioning correctly", e);
}
}
好的,这样我们就剩下了 CBC 加密(没有填充,IV 为零):
private static final byte[] ENCRYPTION_KEY = Hex.decode("448D3F076D8304036A55A3D7E0055A78");
private static final byte[] PLAINTEXT = Hex.decode("1234567890ABCDEFFEDCBA0987654321");
public static void main(String[] args) throws Exception {
SecretKey desABAKey = createDES_ABAKey(ENCRYPTION_KEY);
Cipher desEDE = Cipher.getInstance("DESede/CBC/NoPadding");
IvParameterSpec zeroIV = new IvParameterSpec(new byte[desEDE.getBlockSize()]);
desEDE.init(Cipher.ENCRYPT_MODE, desABAKey, zeroIV);
byte[] ciphertext = desEDE.doFinal(PLAINTEXT);
System.out.println(Hex.toHexString(ciphertext));
}
我用的是Bouncy Castle十六进制编解码器,但也可以使用其他十六进制编解码器。
既然你想尝试执行3DES-128位CBC模式(填充零)方法,试试这个git https://github.com/meshileya/dukpt用于从密文中得到明文。
既然您已经有了 BDK 和 KSN,请尝试运行下面的方法。
public static void main(String[] args) {
try {
String theksn = "This should be your KSN";
String encrypted = "This should be the encrypted data";
String BDK = "The BDK you mentioned up there";
tracking= DukptDecrypt.decrypt(theksn, BDK, encrypted);
System.out.print("PlainText"+ tracking);
}catch (Exception e){System.out.print(e);}
}
在解密加密数据的过程中,我遇到了一些挑战。如果有人能帮助我度过难关,我会很高兴。
尽管如此,我已经研究了执行此操作的算法,因为我要从设备中获取数据,该设备已经具有其 Base Derivation Key(BDK) , 初始加载的密钥序列号和初始加载的密码输入设备密钥.
在提供的文档中,我们有初始加载密钥序列号、数据加密密钥变体和轨道 2 数据(明文形式)。
在这个例子中,我了解到他们实际上使用了 3DES-128 位 CBC 模式(填充零)方法。
我现在的问题是,明文是如何从加密数据中得到的。如果有人能帮我接通(说明解密这些数据的流程或算法),我将非常高兴。
非常感谢您的宝贵时间。
关于 Oracle 实现的更愚蠢的事情之一是 SecretKeyFactory
不支持 DES ABA 密钥,也称为 "two-key" DES 密钥。
这些用于三重 DES 操作的密钥由单个 DES 密钥 A 和后跟单个 DES 密钥 B 组成。密钥 A 用于 DES EDE 中的第一次和最后一次 DES 迭代(加密-解密-加密) .
如果您留在软件中,您可以创建一种创建此类密钥的方法。问题是生成的密钥实际上有 192 位,这根本不正确 - 它使得无法区分密钥大小。
无论如何,下面的代码可以用来生成DES ABA密钥:
private static final int DES_KEY_SIZE_BYTES = 64 / Byte.SIZE;
private static final int DES_ABA_KEY_SIZE_BYTES = 2 * DES_KEY_SIZE_BYTES;
private static final int DES_ABC_KEY_SIZE_BYTES = 3 * DES_KEY_SIZE_BYTES;
public static SecretKey createDES_ABAKey(byte[] key) {
if (key.length != DES_ABA_KEY_SIZE_BYTES) {
throw new IllegalArgumentException("128 bit key argument with size expected (including parity bits.)");
}
try {
byte[] desABCKey = new byte[DES_ABC_KEY_SIZE_BYTES];
System.arraycopy(key, 0, desABCKey, 0, DES_ABA_KEY_SIZE_BYTES);
System.arraycopy(key, 0, desABCKey, DES_ABA_KEY_SIZE_BYTES, DES_KEY_SIZE_BYTES);
SecretKeySpec spec = new SecretKeySpec(desABCKey, "DESede");
SecretKeyFactory factory = SecretKeyFactory.getInstance("DESede");
SecretKey desKey = factory.generateSecret(spec);
return desKey;
} catch (GeneralSecurityException e) {
throw new RuntimeException("DES-EDE ABC key factory not functioning correctly", e);
}
}
好的,这样我们就剩下了 CBC 加密(没有填充,IV 为零):
private static final byte[] ENCRYPTION_KEY = Hex.decode("448D3F076D8304036A55A3D7E0055A78");
private static final byte[] PLAINTEXT = Hex.decode("1234567890ABCDEFFEDCBA0987654321");
public static void main(String[] args) throws Exception {
SecretKey desABAKey = createDES_ABAKey(ENCRYPTION_KEY);
Cipher desEDE = Cipher.getInstance("DESede/CBC/NoPadding");
IvParameterSpec zeroIV = new IvParameterSpec(new byte[desEDE.getBlockSize()]);
desEDE.init(Cipher.ENCRYPT_MODE, desABAKey, zeroIV);
byte[] ciphertext = desEDE.doFinal(PLAINTEXT);
System.out.println(Hex.toHexString(ciphertext));
}
我用的是Bouncy Castle十六进制编解码器,但也可以使用其他十六进制编解码器。
既然你想尝试执行3DES-128位CBC模式(填充零)方法,试试这个git https://github.com/meshileya/dukpt用于从密文中得到明文。
既然您已经有了 BDK 和 KSN,请尝试运行下面的方法。
public static void main(String[] args) {
try {
String theksn = "This should be your KSN";
String encrypted = "This should be the encrypted data";
String BDK = "The BDK you mentioned up there";
tracking= DukptDecrypt.decrypt(theksn, BDK, encrypted);
System.out.print("PlainText"+ tracking);
}catch (Exception e){System.out.print(e);}
}