【问题标题】:Rijndael 128/256 decryptionRijndael 128/256 解密
【发布时间】:2015-03-27 17:34:29
【问题描述】:

我尝试了许多来自 SO 和整个网络的答案,但仍然没有成功。

我使用以下tool 进行加密。

text to encrypt: tom
key: exo123exo1exo123
input (textfield or selected file above) is: text/binary
Convert output to: [i leave this unselected]
Mode: CTR
Ciphers: Rijndael-128 and Rijndael-256

得到结果后我移动here

并使用 base64 对其进行编码。

然后我复制字符串并将其作为参数发送到我的函数:

public String authenticate(String base64EncodedData){

    byte[] input = Base64.decodeBase64(base64EncodedData);
    byte[] ivBytes = "1234567812345678".getBytes();


    Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");

    cipher.init(
        Cipher.DECRYPT_MODE,
        new SecretKeySpec("exo123exo1exo123".getBytes(), "AES"),
        new IvParameterSpec(ivBytes)
    );

    byte[] plainText = new byte[cipher.getOutputSize(input.length)];
    int plainTextLength = cipher.update(input, 0, input.length, plainText, 0);
    plainTextLength += cipher.doFinal(plainText, plainTextLength);

    return new String(plainText);  
  }

我得到的结果总是与此类似(无论我使用 Rijndael-128 还是 256 加密字符串):

.�v�Y�

当我尝试返回 input 值时 - 我得到了加密字符串。所以 base64 工作得很好。 我做错了什么? 我在这里慢慢生气。 谢谢。

【问题讨论】:

  • 网站的加密方式好像不规范。没有文档说明如何使用这些参数。我找不到可重现的例子。你为什么要使用这个网站?
  • @ArtjomB。我可以使用任何其他的。最终我只是想对 Rijndael128 加密和 base64 编码字符串进行编码。您是否在任何其他网站上测试过此代码?
  • 我回滚了您上次的编辑,因为它实际上无助于回答问题,因为第一个工具太糟糕了(请参阅我的回答)。同样对于未来,请不要回复答案,通过编辑您的问题说答案不起作用。更新秘密gist 中的代码,只更新真正缺失的信息。

标签: java encryption aes rijndael


【解决方案1】:

您的假设和代码存在一些问题:

  1. 第一个工具的输出已经是 Base 64 编码的。 RIJNDAEL-128:r0GR 和 RIJNDAEL-256:yAVy。它不需要第二次编码。它会自动选择此选项,因为无法打印二进制数据。

  2. Java 中没有原生的 Rijndael-256,您必须使用 BouncyCastle。 Rijndael-128 应该是 AES,这意味着两者的块大小都是 128 位。

  3. IV 几乎肯定需要由零字节组成。例如:

    byte[] ivBytes = new byte[16];
    Arrays.fill(ivBytes, (byte)0); // might not be necessary
    

    请注意,CTR 模式不使用 IV,而是使用 nonce。

  4. 在检索字节时始终指定编码:"exo123exo1exo123".getBytes("UTF-8")。最好在任何地方都使用 UTF-8。如果跨使用不同系统编码的系统发送数据,将导致难以发现问题。


第二次查看在线工具对任何东西都没有用处,因为不清楚它是如何工作的。我发现了什么:

  • 无论大小如何,任何密钥都会生成密文,这表明您输入的“密钥”实际上是散列,并且存在一百万种方法可以完成。我可以用上面的方法解密它,所以密钥实际上是按原样使用的,没有散列。这表明密钥被 0x00 字节填充,直到有效的密钥大小。当密钥过大时,可能会被截断。

  • 16 个字符的明文加密为 16 个字节的密文(编码为 24),17 个字符的明文加密为 32 个字节的密文(编码为 44)。这意味着没有使用可识别的填充,实际上可能是零填充。

这是交易破坏者

  • 每次加密时,都会得到不同的密文。在 CBC 模式下,这意味着在加密之前生成一个随机 IV。问题是这个 IV 没有显示出来。所以没有办法完全解密。因此,如果您加密的字符超过 16 个,则可以在解密时恢复除前 16 个字符之外的所有字符。

您不应该让您的系统依赖于闭源在线工具。编写自己的加密工具。一些一般性建议:

  • IV 应该在每次加密时随机生成。它不是秘密的,但应该是唯一的。只需在加密后将其添加到密文中,然后在解密前将其切掉即可。

  • 尽可能使用经过身份验证的模式,如 CCM 或 GCM。自己进行身份验证加密比较困难,但另一种方法是使用 encrypt-then-mac 范例。

【讨论】:

  • 1.好的,所以我不会再次对其进行编码。 2. 我将使用 Rijndael-128 3. 我也可以使用 CBC(将尝试两者) 4. 我将指定编码 完成后,四个步骤将回复您。谢谢
  • 按照你的建议做了。效果是有问题的,低于它的原始部分。还有什么建议吗?
  • 我仔细查看了该工具。这是非常不可用的。我不能推荐任何其他在线工具,但是由于您已经解密,因此编写加密很容易。请注意,您实际上应该使用经过身份验证的加密。所以我在我的回答中提出了一些建议。请仔细阅读。
  • 太棒了!有趣的是,我阅读了更多关于 AES、IV 的信息,并尝试测试了一些在线工具,但我得出的结论与您在“这里是 deal breaker”下所说的相同。还尝试对超过 16 位的字符串进行编码,然后又一次 - 找到了你写的内容,是什么让我想到“哦,好吧,所以我也需要知道 IV”的想法:) 我发现这些工具被关闭是非常不合理的甚至没有试图通知用户后果(根据定义,它们是新手工具应该做什么)。也非常感谢您编辑我的问题。
猜你喜欢
  • 2012-05-06
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-26
  • 2019-04-18
  • 1970-01-01
相关资源
最近更新 更多