Question

I'm wondering if there is some strong (like AES or so.) encryption function that works like this:

  • symetric
  • 2 keys: plaintext -> 2keys ->ciphered text, however it must not matter order of keys, i.e

Key1 (Key2 (plaintext)) == Key2 (Key1(plaintext)) e.g. "commutative" (also required for decryption - you need two keys, doesn't matter order)

thanks

Was it helpful?

Solution

It's not a commutative encryption, but there are well-proven algorithms for secret sharing (note, this is not the same thing as "key agreement.")

Two of the best known methods are Shamir's and Blakley's. In general, these algorithms take a secret and produce many "shares". When enough shares are available to reach a threshold, the secret can be recovered. In the simplest case, two shares are required, but the threshold can be higher.

To explain Shamir's method in simple terms, think about a line on a graph. If you know any two points on the line, you know everything about the line. Any string of bytes, like the encryption key of a symmetric cipher, is just a large number, in base-256. Shamir's algorithm treats this secret as the line's "y-intercept" (the y-coordinate of the line when x=0). Then the line's slope chosen randomly. The y-coordinates of the line at x=1, x=2, x=3, … are computed, and each point is given to a different share-holder.

If any two of these share-holders get together, they can draw a line through their two points, back to the y-axis. The y-coordinate at where it crosses the axis is the original secret. However, each share-holder has only one point; by themselves, they can't guess anything about the original secret.

The threshold can be increased by increasing the degree of the polynomial. For example, if a parabola is used instead of a line, three shares are needed instead of two.

There's more to a real implementation, like the use of modular arithmetic, but this is the concept behind it. Blakley's approach is similar, but it uses the intersection of planes to encode the secret.

You can play around with an implementation of Shamir's method online.

OTHER TIPS

This can be easily done by putting any block encryption algorithm into CTR mode. CTR mode with a single key looks like:

ciphertext = plaintext XOR cipher(key, counter)

Where counter is initialized to your IV and incremented for each block. Decryption is exactly the same operation. As such, if you CTR-encrypt twice with two keys, you get:

ciphertext = plaintext XOR cipher(key0, counter) XOR cipher(key1, counter)

And since XOR is commutative, you can reverse it in either order.

This has the nice property that you don't need to have all keys in the same location. Consider: Alice, Bob, and Charlie are participating in a protocol in which Charlie will double encrypt data for both Alice and Bob (this protocol will assume all point-to-point communication is secured through usual SSL-like channels):

  1. Alice and Bob perform an authenticated Diffie-Helmann exchange to produce the IV. This IV is then sent to Charlie.
  2. Alice computes digest(key0, IV + ctr) for ctr = 0...number-of-ciphertext-blocks, and sends the result KS_A to Charlie
  3. Bob computes digest(key1, IV + ctr) for ctr = 0...number-of-ciphertext-blocks, and sends the result KS_B to Charlie
  4. Charlie computes KS_A XOR KS_B XOR plaintext, and sends the resulting ciphertext to both Alice and Bob.
  5. Alice and Bob each sign a tuple (IV, hash(ciphertext), description-of-encrypted-data). This is attached to the ciphertext.

Later, to decrypt:

  1. Charlie (performing the decryption) sends the signed (IV, hash(ciphertext)) tuples to each of Alice and Bob, as well as the ciphertext.
  2. Alice verifies his signed tuple, computes KS_A, and sends ciphertext XOR KS_A = D_A to Charlie
  3. Bob verifies his signed tuple, computes KS_B, and sends ciphertext XOR KS_B = D_B to Charlie
  4. Charlie computes KS = D_A XOR D_B = KS_A XOR KS_B
  5. Charlie computes plaintext = ciphertext XOR KS

The purpose of the signed tuple here and DH exchange is to ensure Alice and Bob can't be tricked into decryption the wrong stream by sending them a different IV. This may not be relevant in your usage scenario. Also, the role of Charlie may be played by Alice or Bob in a real implementation.

If you're worried about the potential security risks of CTR mode, one other option would be to use CTR-mode encryption on a session key, which in turn is used to encrypt in a more normal mode, such as CBC. That is:

sessionkey = RANDOM
IV_0 = RANDOM
IV_1 = RANDOM
enc_sessionkey = sessionkey XOR cipher(key0, IV_0) XOR cipher(key1, IV_0)
ciphertext = enc_sessionkey + IV_0 + IV_1 + cipherCBC(IV_1, sessionkey, plaintext)

Although some other posters have commented on secret sharing, this is overkill if you don't need the property that only a subset of keys are needed for decryption - ie, with secret sharing you might encrypt with three keys, but require only any two to decrypt. If you want to require all keys, secret sharing schemes aren't really necessary.

You can make a commutative encryption algorithm, but the encryption methods must then be limited to commutative operations. This will limit the strength of the encryption function because it greatly reduces the possible encryption methods that can be used. Thus, if a hacker wanted to break your algorithm and new it was commutative, it would greatly improve his chances of breaking it because of the reduction in decryption methods he would need to try. However, it might be okay for your purposes, depending on how much hacking you expect.

Also, I'm not sure if "secret splitting" is what you are going for, as mentioned by atk. I've looked at it briefly, but from what I've seen (at least for the basic case) you can't perform the operations separately, as both keys need to be provided together to perform the encrypt/decrypt actions. In other words you can't call encrypt with one person's key to get a result that you can call encrypt on with a second key. However, if you have both keys available at once, this might be a good method to try.

You're talking about secret splitting. Yes, there's been a lot of research on it. Wikipedia would be a good starting point.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top