Decrypting “SunJCE” AES encrypted data on Android

前端 未结 3 1384
迷失自我
迷失自我 2021-02-11 05:07

We need to write some Android code to decrypt some data sent from our server. Our server team gave us some sample decryption code which uses the \"SunJCE\" provider, which unfo

3条回答
  •  迷失自我
    2021-02-11 05:20

    @Maarten Bodewes was correct: the garbage characters are present in our Java-only module too.

    The problem is that our server side code is padding the input data with zeros before encrypting it. This is so the input matches the block size required for AES.

    There's a good discussion here: Android - Removing padded bits in decryption

    Even though I'm a little uneasy using this "zero padding", here's a utility I wrote to remove it:

    public static String getStringAfterRemovingZeroPadding(byte[] input) {
        if (input == null) {
            return null;
        }
    
        int index = input.length - 1;
    
        while (index >= 0) {
            if (input[index] == 0) {
                // We found some zero padding, look at the next character and see if it's also zero
                // padding
                --index;
            } else {
                // This character is not a zero padding, so go back to the zero padding that we
                // just inspected, or go to the end of the string
                ++index;
                break;
            }
        }
    
        if (index < 0) {
            return "";
        }
    
        return new String(input, 0, index);
    }
    

    ...and here are my unit tests:

    @Test
    public void testRemoveZeroPaddingNull() throws Exception {
        String result = StringUtils.getStringAfterRemovingZeroPadding(null);
        assertThat(result).isNull();
    }
    
    @Test
    public void testRemoveZeroPaddingAllZeros() throws Exception {
        byte[] input = {0, 0};
        String result = StringUtils.getStringAfterRemovingZeroPadding(input);
        assertThat(result).isEqualTo("");
    }
    
    @Test
    public void testRemoveZeroPaddingNoZeros() throws Exception {
        byte[] input = {80, 80, 80};
        String result = StringUtils.getStringAfterRemovingZeroPadding(input);
        assertThat(result).isEqualTo("PPP");
    }
    
    @Test
    public void testRemoveZeroPaddingOneZero() throws Exception {
        byte[] input = {80, 80, 80, 0};
        String result = StringUtils.getStringAfterRemovingZeroPadding(input);
        assertThat(result).isEqualTo("PPP");
    }
    
    @Test
    public void testRemoveZeroPaddingSomeZeros() throws Exception {
        byte[] input = {80, 80, 80, 0, 0, 0, 0, 0};
        String result = StringUtils.getStringAfterRemovingZeroPadding(input);
        assertThat(result).isEqualTo("PPP");
    }
    

提交回复
热议问题