1

I'm working on a security application using my own customized cryptography method, and having a problem on message decryption.

According to the theory, the input has to be padded to meet the required bit to execute the encryption. But the padded bits stays even after the decryption.

Here's an example:

input (before padding) : q
input (after padding)  : 113 0 0 0 0 0 0 0 (in Bytes)

Then I execute some code:

bytes[] a = encrypt(input);
bytes[] b = decrypt(a);

String output = "";
output = new String(b, "UTF-8");

The output on System.out.println is below:

b      : 113 0 0 0 0 0 0 0
output : q[][][][][][][]

I have no idea how to remove the padded bits. I'm currently using the function below:

public String processOutput(String dtxt){
    String result = "";
    int l = dtxt.length();
    for(int i=0;i<l-16;i++) result = result + dtxt.charAt(i);
    for(int i=l-16;i<l;i++){
        if((long)dtxt.charAt(i)!=0){
            result = result + dtxt.charAt(i);
        }
    } return result;
}

But this function will only works if I put the output to a String. What if the output is a file (let's say an image file)? How to remove the padded bits after decryption? Please help.

4

2 回答 2

2

您应该使用填充,例如Cipher.getInstance("AES/CBC/PKCS5Padding"). 正如您现在使用的那样,零填充存在一个问题,即您无法区分以00值字节结尾的纯文本和填充。如果您执行取消填充,那么您至少会遇到最后一个块的问题。当然,对于文本,您可以00在执行字符解码例程之前删除最后的值字节。另一种方法是在纯文本的开头简单地添加一个 64 位大小的指示符。

请注意,默认的 Oracle Java 提供程序没有零填充选项(据我所知),因此您要么必须自己进行取消填充,要么必须使用另一个 JCE 提供程序,例如确实包含零填充的Bouncy Castle 提供程序选项(例如对于Cipher.getInstance("AES/CBC/ZeroPadding").

请注意,关于填充的 Wikipedia 页面对此事有很多话要说。另请注意,CBC 模式本身不提供完整性保护或身份验证,仅提供机密性并且只有在正确使用的情况下。

于 2013-05-23T19:52:33.687 回答
0

您可以在流模式下使用分组密码(例如 AES)来完全摆脱填充。因此,您可以使用例如Cipher.getInstance("AES/CTR/NoPadding"),或者如果您还想包含身份验证标签Cipher.getInstance("AES/GCM/NoPadding")。后者将在密文的末尾添加一些字节,您可以使用这些字节来确保密文是使用正确的密钥创建的,并且密文没有被更改。

请注意,您可能会泄露有关纯文本大小的信息。这对于 CBC 模式也是如此,但在这种情况下,您至少会有 16 字节(块大小)的边距。使用流模式加密,您将加密到完全相同的字节数。另请注意,您需要为具有相同密钥的每个加密使用新的 IV 值,否则您可能会直接将明文暴露给攻击者。

于 2013-05-23T19:59:31.103 回答