【问题标题】:Decrypting DES/CBC/ZeroBytePadding data解密 DES/CBC/ZeroBytePadding 数据
【发布时间】:2018-04-15 11:03:06
【问题描述】:

我有一个令牌和一个解密令牌所需的秘密。我不确定我做错了什么,我不断收到“非法密钥大小”。我的密钥大小是 44 字节。我在静态块中添加 BouncyCastleProvider。下面是我正在尝试做的一个小sn-p。

SecretKeySpec skeySpec = new SecretKeySpec(keyText.getBytes(), "DES");
Cipher des = Cipher.getInstance("DES/CBC/ZeroBytePadding", "BC");
des.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[8]));
byte[] tokenData = des.doFinal(Base64.decodeBase64(token));

【问题讨论】:

    标签: java encryption jce


    【解决方案1】:

    DES 的密钥大小为 8 字节中的 56 位,每个字节的 lsb 保留用于奇偶校验,但通常被忽略。

    所以“我的密钥大小是 44 字节”是不正确的。

    接下来是用于解密的 IV 必须与用于加密的 IV 相同。 DES 的块大小为 8 字节,因此 IV 需要为 8 字节。处理 IV 的一种通用方法是在加密数据前面加上它,IV 不需要保密。

    最后,零填充通常不是一个好的解决方案,它不支持可能以零字节结尾的二进制数据。 PKCS#5 是常用的填充。

    【讨论】:

    • 在大多数情况下,零填充是一个坏主意,但(非三重)DES 总是更糟糕。
    • 最好跳过 AES 的 3DES 权限,这是当前的标准。
    • 我同意您关于零填充的评论,但这只是我们有一个遗留系统,我们需要再使用几天。所以问题在于密钥和加密数据。
    【解决方案2】:

    我的猜测是您的 keyText 是 Base64 编码的。您可能应该对其进行解码以获得 32 字节的 byte[]。在 Java 8 中,您可以执行以下操作:

    byte[] key = java.util.Base64.getDecoder().decode(keyText.getBytes());
    SecretKeySpec skeySpec = new SecretKeySpec(key, "DES");
    Cipher des = Cipher.getInstance("DES/CBC/ZeroBytePadding", "BC");
    des.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[8]));
    byte[] tokenData = des.doFinal(Base64.decodeBase64(token));
    

    另一个问题有关于 Base64 的更多信息。 Converting Secret Key into a String and Vice Versa

    我仍然认为您会收到无效的密钥大小错误。 DES 密钥不是 56 位(加上 8 个奇偶校验位)吗?所以这只会是 8 个字节长而不是 44 或 32 我认为你会在解码 Base64 时得到。

    【讨论】:

    • 是的,DES 使用 8 字节密钥。
    猜你喜欢
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    相关资源
    最近更新 更多