views:

144

answers:

4

I've got a bunch of 48-bit (6 byte) values that I need to encrypt symmetrically. The two requirements are:

  1. The resulting encrypted value needs to also be 48-bits (6 bytes) long. They key itself can be (and would preferably be) much longer to guard again brute force attacks.

  2. The resulting encrypted value needs to be deterministic, i.e. value A using key B will always produce encrypted value C (we encrypt on the fly and show the encrypted data to the user so need to always show the same value)

All block ciphers I've found have used a minimum block size of 64 and appear to be fixed (you can't use an arbitrary block size). Should I be thinking about a stream cipher?

I'm doing this in Java.

Note: I've seen this question and associated answers but wasn't clear on whether the suggestions would satisfy my 2nd requirement.

+3  A: 

(Sorry, I originally misread the requirements thinking it was the INPUT data that needed to be 6 bytes.)

I don't think you can do exactly what you want with standard cryptographic algorithms:

  • the problem with stream ciphers is that standard ones effectively work by generating a stream of pseudorandom bits from the key and then XORing these bits with the plaintext; effectively this means that you should never use the same stream of bits twice (e.g. if you do, then XORing two ciphertexts gives you the same result as XORing the corresponding plaintexts; and in any case with 48 bits, there are only 2^48 possible bitstreams, so you can just test them all by brute force);
  • the problem with block ciphers is that there's no standard one as far as I'm aware that has a block size of 48 bits.

Now, that doesn't mean that a 48-bit block cipher couldn't be developed-- and indeed I dare say there are some out there-- just that none of the bog-standard ciphers that have undergone years of scrutiny from the cryptographic community have that block size.

So I would suggest options are:

  • relax the requirement of a 48-bit ciphertext; for example, TripleDES has a 64-bit block size and is "fairly" secure (equivalent to 112 bit security)[*];
  • in principle, you could implement your own block cipher with whatever block size you require, sticking as close as you can to a standard design, e.g. a Feistel network following some generally recommended design principles-- as a starting point, see Schneier, "Applied Cryptography", pp. 346ff, "Theory of Block Cipher Design".

The obvious problem with the latter option is that, whist standard block ciphers are generally based on common general principles, they adopt particular design decisions that have been subject to considerable scrutiny; yours presumably won't be.

I would also recommend standing back a bit from the problem (or perhaps explaining a bit more what you're trying to do), because it seems to be based on requirements that would normally go against good security practice (having the same plaintext always encrypt to the same ciphertext is something one would normally specifically avoid, for example). So you could have the best designed Feistel cipher in the world, but introduce some other vulnerability in how you're using it.

[*] TripleDES is generally not recommended because AES gives better security more efficiently (you might like to see some comparative timings of block ciphers that I took in Java to see just how bad it is). However, this might not matter in your particular application.

No, just "pad" your data out with some bytes you don't care about (but which are always the same if that's your requirement) so that you reach the size of a block. (If you're using an appropriate padding mode, then this will be done for you.)

Neil Coffey
So when you do that, the padded data has 64 bits. So will have the encrypted data. But the basic requirement was that the encrypted data comes out as 48 bits.
Roland Illig
Yes @Roland is correct - it doesn't meet my first requirement.
Marplesoft
I have no idea how to implement the requirements. I have some solid ideas on how to break encryption schemes that do meet the requirements. So +1 for "I would also recommend standing back a bit from the problem (or perhaps explaining a bit more what you're trying to do), because it seems to be based on requirements that would normally go against good security practice"
emory
emory: How would you break the encryption? It doesn't help the poster to know that you have ideas if he doesn't know what they are.
Gabe
@Gabe, If I understand the requirements correctly, then the encryption is http://en.wikipedia.org/wiki/Substitution_cipher. Given enuf ciphertext, I would do a frequency analysis.
emory
emory: You can't do frequency analysis on 6 bytes of ciphertext. Besides, I don't see how a deterministic 48bit->48bit function is necessarily a substitution cipher.
Gabe
EORing? Winnie the pooh does crypto? ;)
Nick Johnson
+1  A: 

You can use a stream cipher only, if you have a unique salt for every encryption (don't even think about re-using the same salt, as that would be trivial to break).

When you have such unique values (e. g. a sequence number that's already associated with your values), you can use e.g. the stream cipher RC4-drop.

When you don't have such unique numbers already, you probably can't use a stream cipher, because you only have 48 bits for your result (so no space left for the salt.)

As for a block cipher with 48 bits - sorry, I don't know such a cipher, either. Maybe what you can do, is combining four 48 bit values into a 192 bit value, resulting in three 64 bit blocks, encode them, and then split them into four 48 bit values again. (I have no idea, if that would be possible in your situation or not?)

Chris Lercher
+3  A: 

Consider format preserving encryption.

Accipitridae
I've been posting that link frequently as of late!
GregS
@GregS: Well, unfortunately it is necessary to repost the same answers again and again here. Especially since the proposed alternatives are usually weak. E.g.http://stackoverflow.com/questions/858476
Accipitridae
+1  A: 

If you have a unique counter / sequence number associated with each plaintext value, then you can just use any block cipher in CTR (counter) mode.

To encrypt value V that is sequence number N under key K:

  • Expand N to the size of a block;
  • Encrypt N with the block cipher and key K;
  • Take the first 48 bits of the result and XOR them with V.

Decryption is the same. The most important thing to remember with this method is:

Never, ever use the same key and sequence number to encrypt two different values.

Sequence numbers must be unique. If your sequence restarts, you must use a new key.

caf