views:

304

answers:

3

Does anybody know a seekable alternative to .NET's CryptoStream?

It is OK if the alternative supports Seek only in "read" mode or if it is limited to e.g. AES256.

+2  A: 

I think such an implementation would not be very useful, as Seek operations can only be performed in (relatively, depending on the algorithm) constant time with ECB-style chaining, i.e. encrypting blocks separately - and that's highly unrecommended - see the image in this Wikipedia article for a startling example of insecurity.

Seems to me you would be better off by copying into / out of a MemoryStream or similar wrapping technique.

Barry Kelly
I see the problem. However, there seem to be several approaches that allow secure block-wise encryption, for example http://en.wikipedia.org/wiki/Disk_encryption_theory#XTS which is used by TrueCrypt.
Stefan Schultze
Disk encryption encrypts each block independently, which is how it gets its random seeking.
Barry Kelly
+2  A: 

Block-wise encryption is perfectly secure. It's just ECB that's problematic. An implementation could probably be written using either OFB or CTR mode. However, I've never managed to locate one. May bite the bullet and write it...

UPDATE:

So I did write an implementation of this. For various reasons I'm not going to post it here right now (I'll try to at some point), but here are a few pointers for anyone looking to do this:

Use a RijndaelManaged transform in CBC mode. You're going to calculate the cipherstream block by block. You can do this by initializing a key and an empty (all zero) iv in the transform - the actual iv will be calculated on a block by block basis.

You'll want to have a method that calculates the input to the current block by concatenating or otherwise computing the nonce plus iv plus counter. You can do several optimizations here, including precomputing the nonce & iv (this method will get called many times, so it's probably worth it).

e.g. byte[] GetCurrentCounterBlock(byte[] nonce, byte[] iv, UInt32 counter)

(note: by "iv" here I mean what NIST calls the IV, the middle part of the whole block, which other people call the IV collectively)

You're going to use this method inside a loop that's enciphering your data - call this the first time and then subsequently at block boundaries to update the current cipher stream. This method provides the input to the TransformBlock method of the transform. Take the output from the transform and XOR the result against the current block of data. Use transform.Reset() after each block is encrypted! Otherwise, CBC will try to use the output from the transform as input to the next. There may be a more clever way to do this with .NET, but I can't figure it out. I know BouncyCastle supports OFB "natively" so that may be a better options, but this is a nice fast way to get a highly reusable cryptostream without external deps.

Anyway, the key is that this whole method (I call it AesCtr256.Process - but you could easily be more generic) works with an arbitrary range of data inside the cipher stream. You can easily use this method inside a custom Stream class. This will allow seeking to arbitrary locations inside the stream on both reads and writes, and give you byte-aligned data to work with (really nice, as you can now have a crypto stream that actually reports the true data length!).

To put it another way, you calculate the cipher stream for arbitrary portions of the stream, and then simply xor against the cipher or plain text to encrypt/decrypt.

Two last things: 1.) I highly recommend reusing the transform for the life of the stream - creating these is expensive. 2.) If you're going to implement this write unit tests against NIST vectors or similar. Don't assume you got this right - just because the output looks random, doesn't mean it's correctly enciphered :).

If anyone has any thoughts on a better approach or how I've totally mucked up a really critical piece of code, please post, thanks! Again, I really will try to post the real thing here eventually.

Jeff
A: 

Check this, it might help ;)

http://admincraft.net/arts/2WRCS.html

AdminCraft