Rijndael 128/256解密

时间:2015-03-27 17:34:29

标签: java encryption aes rijndael

我尝试了很多来自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工作正常。 我做错了什么? 我在这里慢慢生气。 谢谢。

1 个答案:

答案 0 :(得分:2)

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

  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。如果您跨使用不同系统编码的系统发送数据,将导致很难发现问题。


  5. 第二次看在线工具不能用于任何事情,因为目前还不清楚它是如何工作的。我找到了什么:

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

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

    这是交易破坏者

    • 每次加密某些内容时,都会获得不同的密文。在CBC模式中,它意味着在加密之前生成随机IV。问题是没有显示这个IV。所以没有办法完全解密。因此,如果您加密超过16个字符,那么当您按照我在本答复的第一部分中描述的方式解密时,您可以恢复除前16个字符以外的所有字符。

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

    • 每次加密时都应随机生成IV。它不是秘密,但应该是独一无二的。只需在加密后将其添加到密文,然后在解密前将其切片。

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