1

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.

Community
  • 1
  • 1
Kaitlyn
  • 789
  • 10
  • 27
  • 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? – Lasse V. Karlsen Aug 01 '15 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. – Kaitlyn Aug 01 '15 at 19:58
  • Why? What kind of risk would be involved? And still, what is the question here? – Lasse V. Karlsen Aug 01 '15 at 20:00
  • @LasseV.Karlsen The question is how to encrypt and decrypt a file using RC4 encryption algorithm, in C# code. Preferably with a code example, that can accept a FileStream as input. – Kaitlyn Aug 01 '15 at 20:01
  • 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? – Lasse V. Karlsen Aug 01 '15 at 20:02
  • Would that be more secure than CryptoStream? – Kaitlyn Aug 01 '15 at 20:03
  • Are you worried about someone attacking the encrypted data or the program you're writing? – Lasse V. Karlsen Aug 01 '15 at 20:04
  • Just the program. As stated, I know RC4 is weak as an encryption, but currently, the other two encryption algorithms I am using as a sort of benchmark in the same program uses FileStream then CryptoStream. However, posting that code will most likely confuse people like it did before. – Kaitlyn Aug 01 '15 at 20:05
  • @LasseV.Karlsen he already established the code doesn't work but didn't want to set about fixing it either. – BugFinder Aug 01 '15 at 20:09
  • @BugFinder I didn't really establish any code, in fact, I already deleted that code from the IDE, as it was but a random piece of code in the first place. And I'm not a guy either.... – Kaitlyn Aug 01 '15 at 20:10
  • .. sorry. I fell for the gender issue too.. I'm ashamed. – BugFinder Aug 01 '15 at 20:11
  • This link (and another) was removed - http://dotnet-snippets.com/snippet/rc4-encryption/577 - does that mean the code as posted does not work, or just that it didn't show how to do *files* ? – Lasse V. Karlsen Aug 01 '15 at 20:11
  • The act of securing *a program* is a lot more than just picking or implementing an encryption algorithm. Do you really need to protect *the program*? – Lasse V. Karlsen Aug 01 '15 at 20:12
  • The latter. And since it also caused confusion again as well... which I am keen to avoid after the grief it caused BugFinder. And it's not more of really protecting the program, more of a sure way to be able to encrypt it properly, and to be able to handle all sorts of files, no matter their extensions or type. I just prefered Stream, as it was more of a standard in my program as of now, as files are processed as a stream. Unless byte arrays do not change the speed of how large files in streams are processed? (E.g. A 1GB file, or more, maybe even 5GB+) – Kaitlyn Aug 01 '15 at 20:13
  • @BugFinder Sorry though, if my words come across as jarring or rude. I'm just frustrated that somehow I'm not able to get my real point/question across. – Kaitlyn Aug 01 '15 at 20:24
  • Have you looked at the BouncyCastle library? it implements the RC4 cipher. – Nasreddine Aug 01 '15 at 20:43
  • @Nasreddine No, not really, as I was trying to not include any third-party libraries, though the real reason was that the last time I saw that library, it looked quite confusing to me. (I found an answer containing part of that library when I was researching on AES, http://stackoverflow.com/questions/202011/encrypt-and-decrypt-a-string/10366194#10366194 . i should probably mention that I'm not using any code from that answer in my program right now. Not sure how to use that class either) – Kaitlyn Aug 01 '15 at 20:47
  • @Nasreddine Must the whole library be used/added/embedded? Is there no way to just only embed the relevant parts of the library? And as according to this page (https://bouncycastle.org/specifications.html)... there may be patents on parts of that library, which may prove to be troubling sooner or later. (No, the program the code is going is not going to be sold or anything, but I still want to avoid any potential legal issues either) – Kaitlyn Aug 01 '15 at 21:09
  • Yes, you have to reference the library. as for the legal side, well, I can't comment on that since IANAL. – Nasreddine Aug 01 '15 at 21:12
  • 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. – halfer Sep 09 '15 at 17:37

1 Answers1

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.

Nasreddine
  • 33,475
  • 17
  • 73
  • 91
  • 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? – Kaitlyn Aug 01 '15 at 21:59
  • 1
    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. – Nasreddine Aug 01 '15 at 22:11
  • 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? – Kaitlyn Aug 02 '15 at 01:56
  • 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 :)). (http://codeshare.io/hOmuF) Is it due to the way the data is being returned? – Kaitlyn Aug 02 '15 at 04:26
  • oh... so it's not meant to appear remotely like the http://rc4.online-domain-tools.com/ encrypted text? Thanks again, you helped me a lot :) – Kaitlyn Aug 02 '15 at 10:45