【问题标题】:Decrypt a data by 3DES-128 bits CBC Mode (padding zero)) using java使用java通过3DES-128位CBC模式(填充零)解密数据
【发布时间】:2017-01-27 10:07:32
【问题描述】:

在解密加密数据的过程中,我遇到了一些挑战。如果有人能帮我完成,我会很高兴。

虽然,我已经研究过执行这个操作的算法,因为我要从一个设备中获取我的数据,它已经有它的 Base Derivation Key(BDK)最初加载的密钥序列号初始加载的密码输入设备密钥

在提供的文档中,我们有初始加载的密钥序列号数据加密密钥变体track 2 Data(位于明文)

在这个例子中,我被告知他们实际上使用了 3DES-128 位 CBC 模式(填充零)方法。

我现在的问题是,明文是如何从加密数据中获得的。如果有人能帮我完成(说明解密此数据时使用的流程或算法),我会很高兴。

非常感谢您的宝贵时间。

【问题讨论】:

  • 3DES 是 168 位。有时部分密钥会被重用,所以它是 112 位的。不同之处在于每字节仅使用 MS 7 位,LS 位最初用于奇偶校验,但在当前使用中通常被忽略。但是,DES 和 3DES 不应该在新工作中使用,而是使用取代 DES 的 AES。如果不使用填充,则输入数据必须始终是块大小的倍数,DES 为 8 字节,通常使用 PKCS#5 填充。
  • 您的测试数据表明您正在谈论 DUKPT 密钥。这是一个相当复杂的过程。在实现它时,我在this blog 中找到了很多帮助。
  • @zaph 但是,在它的加密过程中,我被告知,3DES 实际上被用于它的加密。这是否意味着可以使用 AES 解密 3Des 加密数据?
  • @EbbeM.Pedersen 非常感谢那个指针,我也已经尝试过使用流程,但我没有做对。

标签: java encryption cryptography 3des dukpt


【解决方案1】:

关于 Oracle 实现的一个更愚蠢的事情是SecretKeyFactory 不支持 DES ABA 密钥,也称为“双密钥”DES 密钥。

这些用于三重 DES 操作的密钥由单个 DES 密钥 A 和后跟单个 DES 密钥 B 组成。密钥 A 用于 DES EDE 中的第一次和最后一次迭代(加密-解密-加密)。

如果您留在软件中,您可以创建一种方法来创建此类密钥。问题是生成的密钥实际上有 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 十六进制编解码器,但也可以使用其他十六进制编解码器。

【讨论】:

  • 非常感谢您的解释,我想知道您使用的 Bouncy Castle 十六进制编解码器 bcprov-jdk15-130.jar 和 bcprov-1.45.jar 但仍然看不到 .toHexString方法。再次感谢您的宝贵时间。
  • 还有,我怎样才能解密和加密使用 KSN 和 BDK 密钥加密的数据??
  • 我会在家里检查编解码器,但这并不重要。我不知道协议,所以我不确定如何处理其他密钥。
【解决方案2】:

由于您想尝试执行 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);}

    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-02
    • 1970-01-01
    • 2017-03-27
    相关资源
    最近更新 更多