Android - Removing padded bits in decryption

天大地大妈咪最大 提交于 2019-12-21 03:01:19

问题


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.


回答1:


You should use a padding such as Cipher.getInstance("AES/CBC/PKCS5Padding"). Zero padding, as you are now using, has got the problem that you cannot distinguish between a plain text ending with 00 valued bytes and the padding. If you perform unpadding then you will at least have trouble with the final block. Of course, with text you can just removed the 00 valued bytes at the end before you perform the character decoding routine. Another method is to simply add a 64-bit size indicator at the start of your plain text.

Note that the default Oracle Java providers do not have zero padding options (as far as I know) so you either have to do the unpadding yourself, or you will have to use another JCE provider such as the Bouncy Castle provider that does include zero padding options (e.g. for Cipher.getInstance("AES/CBC/ZeroPadding").

Note that the Wikipedia page on padding has much to say on the matter. Also note that CBC mode does not provide integrity protection or authentication by itself, only confidentiality and only if used correctly.




回答2:


You can use a block cipher such as AES in streaming mode to get rid of the padding altogether. So you could use e.g. Cipher.getInstance("AES/CTR/NoPadding") or if you also want to include an authentication tag Cipher.getInstance("AES/GCM/NoPadding"). The latter will add some bytes to the end of your ciphertext which you can use to make sure that the ciphertext was created using the correct key, and that the ciphertext was not altered.

Beware that you may leak information about the size of the plain-text. This is also true for CBC-mode but in that case you will at least have a 16 byte (block size) margin. With streaming mode encryption you will encrypt to precisely the same number of bytes. Also be aware that you need to use a fresh IV value for each encryption with the same key, otherwise you may directly expose the plaintext to an attacker.



来源:https://stackoverflow.com/questions/16713910/android-removing-padded-bits-in-decryption

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!