I want to encrypt a large file using RC4. But what happens if the encrypted file gets corrupted (bytes modified or lost)? Can I still decrypt the rest of the file correctly?

If not, what is the best solution? Split the file in X chunks, and encrypt those seperately?


If a large file enciphered using RC4 is partially corrupted, the uncorrupted portions remains fully decipherable, including what's after a corrupted portion if the corruption modifies this data's value, but not its length (a length corruption could occur e.g. for serial communication, but is unlikely on a hard disk). This is a property of all stream ciphers.

An exception is when there's an IV somewhat combined with the key to form the full key input of RC4, and this IV is corrupted; then the whole file is undecipherable, essentially as if the key was lost.

Another practical exception is if the deciphering program somewhat stops when encountering a corrupted disk block, or gets the keystream out of sync with the ciphertext in this situation (which is not unseen!); to recover from this without fixing the program, the corrupted file can first be copied to a good media, with the corrupted blocks replaced by arbitrary data (rather then removed).

Finally, the deciphering program could include a provision to check file integrity, and refuse to output the plaintext if it is corrupted; in that case, this deciphering program needs a change to skip this check.

|improve this answer|||||
  • $\begingroup$ I write the 200 MB file in 2 KB blocks. Does it make sense to reset the keystate for every block? Or is it better to initialize it only once for the whole file? $\endgroup$ – Muis Mar 19 '15 at 8:51
  • 1
    $\begingroup$ In any case, you MUST NOT "reset the keystate" to the same state for every block, which would be the equivalent of re-using a pad in the One Time Pad. $\;$ If the file is read and written sequentially, it is best to use RC4 as designed, that is without resetting it. If you must access the blocks in random order, you need a carefully thought RC4 variant, perhaps where the key and block number are somewhat combined to "reset the keystate". $\endgroup$ – fgrieu Mar 19 '15 at 10:30
  • $\begingroup$ The problem is that the secret is easily predictable (you add known bytes to the key). And the reset is kind of expensive, i wish I could keep the state and still be able to do random reads $\endgroup$ – Muis Mar 19 '15 at 10:48
  • $\begingroup$ If RC4 was secure in a related-key setup, you could "append the blocknumber to the key", run a separate RC4 for each block, and that would be safe as long as a block is not modified (which amounts to keystream reuse). Problem is, RC4 key scheduling is insecure when used in this way. $\;$ We are wandering far away from the original question when we deal with security issues in unspecified variants of RC4, and with your performance issue; you should ask a separate question. Be careful to state your requirements/constraints, including if you have to use RC4 (or just consider this). $\endgroup$ – fgrieu Mar 19 '15 at 10:59
  • $\begingroup$ I just consider it, I dont have to do nothing $\endgroup$ – Muis Mar 19 '15 at 11:10

The RC4 stream cipher does not mix the data into the key stream. The key stream it generates only depends on the secret key with which it was initialized. And "corruption", that means "flipped bits in the ciphertext" will result in "flipped bits in the cleartext" after decryption, even in exactly the same positions, as in the ciphertext, so classical error-correction-mechanisms will work on the encrypted data.

On the other hand, if you "lose bits" on the way, your data stream will get "out of sync" with your key stream and you get garbage when deciphering the data.

If you are free on the choice of your algorithm, please note that you can turn a block cipher (e. g. AES) into a stream-cipher by running it in counter-mode (or related modes like GCM).

Note that you must not reuse the same counter values AND key for different messages. Otherwise, an adversary can XOR the ciphertext messages, which reveals the XOR of the two plaintext messages, as the key stream cancels out in this operation, so no matter what key you use, you always get the same information about the plaintexts. Normally, confidentiality is defined as an adversary's inability to compute any function over plaintexts, as long as he's only in posession of the ciphertexts (and not the plaintexts or the keys, etc.). If you re-use keys and counters, that property is no longer given (the adversary can calculate M1 xor M2, if he only knows C1 and C2), so you do no longer achieve confidentiality with this scheme.

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.