views:

46

answers:

2

My recent turn-on is using BinaryFormatter instead of some database product. I have an idea to write simple 64bit number into hardware dongle, and encrypt my files with it - via simple XOR operation. Just so it can't be readable at some other end. Do I derive from Stream, or what?

I know I can simply put that number into the file and check against it on reading, but... I'll feel better if it's XORed all the way.

+2  A: 

Note that XOR is going to be incredibly easy to break if the other end knows anything about the original data. If it knows the correct 8 bytes at any position, your "encryption" is immediately broken. Are you really sure you want to do this? Coming up with your own encryption scheme is almost always a bad idea - is there any reason you don't want to use one of the many encryption algorithms built into the framework? Sure, use a hardware dongle to derive the key - but then use a normal CryptoStream.

However, if you really want to do this, there are two obvious options:

  • Build a stream wrapper, yes. Unless you really need to support the async operations, I wouldn't do so - it'll make things tougher. Write a stream implementation which takes another stream to proxy to as well as the long value to XOR with, and then whenever you read or write data, apply the XOR.

  • Build an implementation of ICryptoTransform. Then you can potentially get CryptoStream to do all the heavy lifting in terms of the stream stuff - you just need to know how to transform a block at a time. I believe this should be pretty simple, but I can't say I've ever done it myself.

Jon Skeet
true... this especially apparent if the file contains large amounts of zeroes. The zeroes are transformed into your EOR key, making it very obvious what your key is if someone does a simple hexfile dump.
Toad
+1  A: 

I'm not going to comment on XOR encryption, that's too silly. Lets focus on practical guidance to implement your custom stream. You should derive it from Stream so it has a familiar interface to the user. Right-click "Stream", Implement Abstract Class. You can leave most of the NotImplementedException throws in place, streams are commonly crippled like this. Add a private FileStream member, it will do the hard work. Then add:

  • A contructor that takes a string argument, the path to the file. Construct the FileStream with it.
  • Implement CanWrite, return true.
  • Implement the Write() method. Do whatever you need to do to the byte[] that the client passed. You typically need your own byte[] buffer, call Flush() if it is getting too large. Or FileStream.Write() directly if you don't need a buffer.
  • Implement the Flush method. Call FileStream.Write() for your buffer, then its Flush().
  • Implement Close and Dispose(), call the corresponding FileStream method.
Hans Passant
Can you add same nice recipe for reading? :)
Daniel Mošmondor