1
votes

I'm playing with RC4 and CRC32 trying to simulate a bit flipping attack, and I'm scratching my head about the behavior of CRC32 in Java. As far as I know, this should be a deterministic result based on a polynomial calculation. What I'm seeing, however, is that regardless of whether the text actually changes or not, the CRC changes in an unpredictable manner. The Javadoc simply states for update() on a byte array: Updates the CRC-32 checksum with the specified array of bytes., and for getValue(): Returns CRC-32 value. Is there some sort of salt or PRF involved here for which I'm not accounting (I wouldn't think so)?

Output:

run:
Ciphertext = [B@34e51b72, and CRC = 232697804
Now ciphertext = [B@34e51b72, and CRC = 1990877612
Now ciphertext = [B@34e51b72, and CRC = 1720857375
Now ciphertext = [B@34e51b72, and CRC = 4144065286
Now ciphertext = [B@34e51b72, and CRC = 1992352640
BUILD SUCCESSFUL (total time: 1 second)

code:

 package rc4_crc32;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.util.zip.CRC32;
public class RC4_CRC32 {
    public static void main(String[] args) throws Exception{ 
        byte[] key, ciphertext;
        CRC32 c = new CRC32();
        javax.crypto.Cipher r;
                 r = Cipher.getInstance("RC4");
                 key = "1@m@L33tH@x0r!".getBytes("ASCII");
                 SecretKeySpec rc4Key = new SecretKeySpec(key, "RC4");
                 r.init(Cipher.ENCRYPT_MODE, rc4Key); 
                 ciphertext = r.update("Secret!".getBytes("ASCII"));                    
                 c.update(ciphertext);                 
                 System.out.println("Ciphertext = " + ciphertext + ", and CRC = " + c.getValue());     
                 ciphertext[0] = (byte)0x2c;
                 c.update(ciphertext);
                 System.out.println("Now ciphertext = " + ciphertext + ", and CRC = " + c.getValue());
                 c.update(ciphertext);
                 System.out.println("Now ciphertext = " + ciphertext + ", and CRC = " + c.getValue());
                 c.update(ciphertext);
                 System.out.println("Now ciphertext = " + ciphertext + ", and CRC = " + c.getValue());
                 c.update(ciphertext);
                 System.out.println("Now ciphertext = " + ciphertext + ", and CRC = " + c.getValue());
    }    
}
1

1 Answers

3
votes

update() is for incrementally calculating the checksum over a sequence of bytes. Your code calculates the crc32 over the concatentation of all the ciphertexts provided to update() on the same CRC32 object.

Try

c.reset()
c.update(ciphertext);   
System.out.println("Now ciphertext = " + ciphertext + ", and CRC = " + c.getValue());