views:

358

answers:

5

Is there a well-known (to be considered) algorithm that can encrypt/decrypt any arbitrary byte inside the file based on the password entered and the offset inside the file.

(Databyte, Offset, Password) => EncryptedByte
(EncryptedByte, Offset, Password) => DataByte

And is there some fundamental weakness in this approach or it's still theoretically possible to build it strong enough

Update: More datails: Any cryptographic algorithm has input and output. For many existing ones the input operates on large blocks. I want to operate on only one byte, but the system based on this can only can remap bytes and weak by default, but if we take the position in the file of this byte, we for example can take the bits of this position value to interpret them as some operation on some step (0: xor, 1: shitf) and create the encrypted byte with this. But it's too simple, I'm looking for something stronger.

A: 

Basically what you need to do is generate some value X (probably 1 byte) based on the offset and password, and use this to encrypt/decrypt the byte at that offset. We'll call it

X = f(offset,password)

The problem is that an attacker that "knows something" about the file contents (e.g. the file is English text, or a JPEG) can come up with an estimate (or sometimes be certain) of what an X could be. So he has a "rough idea" about many X values, and for each of these he knows what the offset is. There is a lot of information available.

Now, it would be nice if all that information were of little use to the attacker. For most purposes, using a cryptographic hash function (like SHA-1) will give you a reasonable assurance of decent security.

But I must stress that if this is something critical, consult an expert.

Artelius
Stream ciphers is not the answer since I want to encode/decode arbitrary byte of which the position in only known. It's only possible If the pseudorandom generator stream can be accessed arbitrarily, but it becomes weak in this case
Maksee
Ok then, you could concatenate the offset and the password, take the hash, and XOR the last byte of the hash with the data.
Artelius
+2  A: 

Maybe it's not very efficient but how about this:

for encryption use:

encryptedDataByte = Encrypt(offset,key) ^ dataByte

for decryption use:

dataByte = Encrypt(offset,key) ^ encryptedDataByte

Where Encrypt(offset,key) might be e.g. 3DES or AES (with padding the offset, if needed, and throwing away all but one result bytes)

Curd
In worst case it's probably 16 times slower than AES on a plaintext the same length, but it's better than nothing :)
Maksee
This is basically a CTR-mode cipher with truncated blocks. As good as you're going to get, probably, though I don't see why you can't just read and write whole blocks.
Nick Johnson
One problem with this approach is that if you use the same key for multiple files, you're in trouble because you can use a simple xor to get the keystream back.
Jeff Moser
There is no reason why you _must_ use one key for more files. If there is only one master key, it can be used to derive file dependend keys.
Curd
I think the basic concers put forward by 'Whoever' will always persist, if the algorithms has to work with single bytes. Even if another operation than XOR is used, one particuler byte value (in one particular position) will allways be mapped to the same encrypted byte value. This fact makes it vulnerable to some attacs.
Curd
Yes, Curd, I'd call it the main сonclusion behind my approach and the main flaw. So without extra key sequence, unique to this particular file, the algorithm will be weak
Maksee
+3  A: 

You can use AES in Counter Mode where you divide your input into blocks of 16 bytes (128 bits) and then basically encrypt a counter on the block number to get a pseudo-random 16 bytes that you can XOR with the plaintext. It is critically important to not use the same counter start value (and/or initialization vector) for the same key ever again or you will open yourself for an easy attack where an attacker can use a simple xor to recover the key.

You mention that you want to only operate on individual bytes, but this approach would give you that flexibility. Output Feedback Mode is another common one, but you have to be careful in its use.

You might consider using the EAX mode for better security. Also, make sure you're using something like PBKDF-2 or scrypt to generate your encryption key from the password.

However, as with most cryptography related issues, it's much better to use a rigorously tested and evaluated library rather than rolling your own.

Jeff Moser
The requirement not to use the same counter values again implies that your file must be *immutable* (or at least, append-only) - after byte N has been written, you can't then rewrite it with a different value, because the same counter value will be used. If you want random-access writing and reading within the file, you'll have to break it up into blocks and use a mode like XTS instead.
caf
A: 

One possibility is a One Time Pad, possibly using the password to seed some pseudo-random number generator. One time pads theoretically achieve perfect secrecy, but there are some caveats. It should do what you're looking for though.

job
The main caveat with one time pads is that it is very hard to distribute the key to the receiver securely - remembering that in this case, the key must be as long as the message. The rest of the problems are managerial - making sure that the key is only used once and is destroyed as soon it is used, etc.
Jonathan Leffler
Right, but the key here is the output of a pseudo random number generator seeded by the password, so you just wouldn't want to use the same password twice. I don't know how this change affects the security of the algorithm though.
job
The output of a pseudo-random number generator is NOT a One Time Pad. A One Time Pad must be *actually* random. What you have described is simply a stream cipher.
caf
+2  A: 

If you can live with block sizes of 16 byte, you can try the XTS-mode described in the wikipedia article about Disk encryption theory (the advantage being that some good cryptologists already looked at it).

If you really need byte-wise encryption, I doubt that there is an established solution. In the conference Crypto 2009 there was a talk about How to Encipher Messages on a Small Domain: Deterministic Encryption and the Thorp Shuffle. In your case the domain is a byte, and as this is a power of 2, a Thorp Shuffle corresponds to a maximally unbalanced Feistel network. Maybe one can build something using the position and the password as key, but I'd be surprised if a home-made solution will be secure.

Whoever
During I typed my answer, another answer got accepted that essentially converts the AES/3-DES into a stream cipher. I would not recommend this (see also the wikipedia article cited in my answer), since flipping a bit in the plain text simply flips the same bit in the cipher text. Knowing at one moment both plain and cipher at some position means knowing the plain text for every cipher text at that position forever.
Whoever
PS: I can't comment others answers/question, so someone please copy my comment to the proper place. Thank you very much!
Whoever
PPS: Please downvote the accepted answer from Curd (sorry, Curd, nothing personal) and upvote Jeff Moser's!
Whoever