【问题标题】:can't remove 0 while decryption解密时无法删除 0
【发布时间】:2012-05-22 07:31:37
【问题描述】:

我用 Java 编写了 2 个函数来加密和解密消息。我选择 AES/CBC/PKCS7Padding 作为参数。加密时,我的函数无法添加正确的填充(作为 PKCS7Padding,它不应该添加 0 来填充我的消息),因此在解密时我无法删除消息末尾的 0。 有了代码,我的问题会更清晰

    public static  byte[] encryptStringToData(String message, String key){
        // transform the message from string to bytes
        byte[] array_to_encrypt, bkey;
        try {
            array_to_encrypt = message.getBytes("UTF8");
            bkey = key.getBytes("UTF8");
        } catch (UnsupportedEncodingException e1) {
            array_to_encrypt = null;
            bkey = null;
            return null;
        }

        bkey = Arrays.copyOf(bkey, 32);
        BlockCipher engine = new AESEngine();
        engine.init(true, new KeyParameter(bkey, 0, 32));
        PKCS7Padding pad = new PKCS7Padding() ;

        BufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine),pad); 

        c.init(true, new ParametersWithIV(new KeyParameter(bkey), new byte[16]));

        byte[] encrypted_array = new byte[c.getOutputSize(array_to_encrypt.length)];

        int outputLen = c.processBytes(array_to_encrypt, 0, array_to_encrypt.length, encrypted_array, 0);
        try
        {
            c.doFinal(encrypted_array, outputLen);
        }
        catch (CryptoException ce)
        {
            System.err.println(ce);
            System.exit(1);
        }
        return encrypted_array; 
    }


public static  String decryptDataToString(byte[] message, String key){
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        String decrypted =""; 
        try { 
            byte[] keyBytes = key.getBytes("UTF8"); 

            BlockCipher engine = new AESEngine();
            BufferedBlockCipher c = new PaddedBufferedBlockCipher(new CBCBlockCipher(engine));
            keyBytes = Arrays.copyOf(keyBytes, 32); // use only first 256 bit

            c.init(false, new ParametersWithIV(new KeyParameter(keyBytes), new byte[16]));
            byte[] cipherText = new byte[c.getOutputSize(message.length)];

            int outputLen = c.processBytes(message, 0, message.length, cipherText, 0);
            c.doFinal(cipherText, outputLen);
            decrypted = new String(cipherText,"UTF8");
        }
        catch (CryptoException ce)
        {
            System.err.println(ce);
            System.exit(1);
        } catch (UnsupportedEncodingException e) { 
            e.printStackTrace();
        }

        return decrypted;

    }

结果(十六进制输出)

克莱尔消息:3132333435 尺寸:5 加密消息:561dd9f43ec183fe351776a46276991c 大小:16 解密消息:31323334350000000000000000000000 大小:16

【问题讨论】:

  • 如果您不想填充消息,为什么还要填充?它是加密 API 的要求吗?在这种情况下,请在消息的开头包含长度,以便您知道要删除多少个零。
  • 因为我使用的是 CBC,所以在加密/解密之前似乎需要很好地填充消息。

标签: java aes


【解决方案1】:

你应该检查How do I get started using BouncyCastle? 去除多余字节的代码是:

if (outputLength == output.length) {
    return output;
} else {
    byte[] truncatedOutput = new byte[outputLength];
    System.arraycopy(
            output, 0,
            truncatedOutput, 0,
            outputLength
        );
    return truncatedOutput;
}

在您的代码中转换为:

outputLen += c.doFinal(cipherText, outputLen);
if (outputLen == cipherText.length) {
    decrypted = new String(cipherText,"UTF8");
} else {
    byte[] truncatedOutput = new byte[outputLen];
    System.arraycopy(
            cipherText, 0,
            truncatedOutput, 0,
            outputLen 
        );
    decrypted = new String(truncatedOutput,"UTF8");
}

【讨论】:

  • 它有效!我以为 PKCS7Padding 会自动取消填充,但是.. 好吧,我自己删除填充并不重要。非常感谢^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-15
  • 2012-12-26
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多