XOR on streams, reading and writing
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?
开发者_如何学JAVAI 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.
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 getCryptoStream
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.
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.
精彩评论