2

My question is, how do I encrypt and decrypt a file in C# using the RC4 encryption algorithm?

This is not a duplicate of these questions:

I do however acknowledge that at first glance, this question will appear like a duplicate of this question, however, it is around 7 months old, and still has no answer with working code that solves the question directly.

I have however referred to the below links, but none of them answers the question fully, or in fact, at all.

I do know that the built-in System.Security.Cryptography library in Visual Studio 2013 supports RC2, but what I want to focus on right now is RC4, as part of a research. I know it is weak yes, but I'm still using it. No important data is going to be using this encryption.

Preferably with a code example, that accepts a stream as an input. I have caused great confusion, as I did not describe my concerns properly. I am opting for a stream input, due to the concern that any kind of other input may cause a decrease in the speed of processing large files.

Specifications: NET Framework 4.5, C#, WinForms.

20
  • It seems the first (of the 2 last) links posts code for encrypting a byte array. Is the question how to use that or how to adapt it to work with files? Couldn't you just load the entire file into a byte array, encrypt it with RC4 (with the code from that link) and then write it out to a new file? Or perhaps that code doesn't work? Commented Aug 1, 2015 at 19:57
  • I would think that changing the file to a byte array might be more riskier than just using a stream, and I would thus prefer to not such a risk. Commented Aug 1, 2015 at 19:58
  • Why? What kind of risk would be involved? And still, what is the question here? Commented Aug 1, 2015 at 20:00
  • 1
    And wouldn't that just be to read the entire file stream into a byte array, call the code from that link, and then ... write it out to another stream or something? Commented Aug 1, 2015 at 20:02
  • 1
    I'm upvoting, as you have clearly put a lot of research into this. However, my feedback: keep questions as succinct as you can. It's best not to make requests as to how people should (or should not) vote - at worst a question with this level of detail might suffer one or two downvotes, and it does not matter - they're only unicorn points! Also, there is no value in repeating information deliberately in a post - if someone is unclear about something they can just read it again. Commented Sep 9, 2015 at 17:37

1 Answer 1

1

Disclaimer: While this code works, it might not be correctly implemented and/or secure.

Here's an example of file encryption/decryption using the BouncyCastle's RC4Engine:

// You encryption/decryption key as a bytes array
var key = Encoding.UTF8.GetBytes("secretpassword");
var cipher = new RC4Engine();
var keyParam = new KeyParameter(key);

// for decrypting the file just switch the first param here to false
cipher.Init(true, keyParam);

using (var inputFile = new FileStream(@"C:\path\to\your\input.file", FileMode.Open, FileAccess.Read))
using (var outputFile = new FileStream(@"C:\path\to\your\output.file", FileMode.OpenOrCreate, FileAccess.Write))
{
    // processing the file 4KB at a time.
    byte[] buffer = new byte[1024 * 4];
    long totalBytesRead = 0;
    long totalBytesToRead = inputFile.Length;
    while (totalBytesToRead > 0)
    {
        // make sure that your method is marked as async
        int read = await inputFile.ReadAsync(buffer, 0, buffer.Length);

        // break the loop if we didn't read anything (EOF)
        if (read == 0)
        {
            break;
        }

        totalBytesRead += read;
        totalBytesToRead -= read;

        byte[] outBuffer = new byte[1024 * 4];
        cipher.ProcessBytes(buffer, 0, read, outBuffer,0);
        await outputFile.WriteAsync(outBuffer,0,read);
    }
}

The resulting file was tested using this website and it appears to be working as expected.

Sign up to request clarification or add additional context in comments.

5 Comments

Just to check, is there no way for the Read and Write to not be Async? Or at least is there a way for another method/timer to know when it has completed, and thus alert the user?
Yes there's a way but they are blocking operations which is bad if not handled properly especially if you're executing this on the UI thread (your UI will stop responding). To make them non async just remove the await keyword change ReadAsync and WriteAsync to Read and Write respectively.
Oh so there's a risk.... So I assume thus if hypothetically, if I also wanted to use the library to encrypt text, your code can do it too, just that I have to remove lines 8 to 31, and lines 35 to 36, and add a few lines before "byte[] outBuffer = new byte[1024 * 4]" to convert a string into bytes?
Somehow, the way I adapted your code to also be able to encrypt text strings seems to not be working quite right (the code you provided encrypted files nicely though, thanks :)). (codeshare.io/hOmuF) Is it due to the way the data is being returned?
oh... so it's not meant to appear remotely like the rc4.online-domain-tools.com encrypted text? Thanks again, you helped me a lot :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.