Derived IV for AES - encryption

If a new random AES key is generated every time a transaction takes place between parties. Does it matter if the IV is derived from the key?
For example:
Bob sends a AES-CBC encrypted message to Alice. For which Bob created a random 256 bit key. Now say Bob uses the first 128 bits of sha256(key) to get an IV for encryption.
Bob secures the key with RSA encryption using Alice's public key. Now Alice decrypts the key using her RSA private key. Then Alice uses the first 128 bits of sha256(key) to obtain the IV to use to do decryption.
Alice and Bob continue to talk using the same procedure but generate a new random key each time a message is sent.
Now say Eve can read Bob and Alice's cipher texts both the AES and RSA. Also Eve knows that Bob and Alice are deriving the IV from the key and the method used. That still does not help Eve crack the message?

If your key is different for each message then you don't need an IV (in other words, your IV may consists of all zeros). What you really should not do is encrypt the IV using the same key, or derive the IV from the key.
The IV is used to allow for key reuse. If you don't reuse the key (even in time) then the IV is useless. Because the IV is for key reuse, deriving it from just the key is obviously not the thing to do, and you may easily compromise the key if you would reuse it.

Related

How to decrypt AES on the server side? [duplicate]

If I am using Rijndael CBC mode, I have no idea why we would need salt.
My understanding is even if people know the password, but he cannot get the data without IV.
So from my perspective, password + IV seem to be sufficent secure.
Do I get anything wrong?
Yes, you need all of these things.
Salt (and an "iteration count") is used to derive a key from the password. Refer to PKCS #5 for more information. The salt and iteration count used for key derivation do not have to be secret. The salt should be unpredictable, however, and is best chosen randomly.
CBC mode requires an initialization vector. This is a block of random data produced for each message by a cryptographic random number generator. It serves as the dummy initial block of ciphertext. Like the key-derivation salt, it doesn't have to be kept secret, and is usually transmitted along with the cipher text.
The password, and keys derived from it, must be kept secret. Even if an attacker has the parameters for key derivation and encryption, and the ciphertext, he can do nothing without the key.
Update:
Passwords aren't selected randomly; some passwords are much more likely than others. Therefore, rather than generating all possible passwords of a given length (exhaustive brute-force search), attackers maintain a list of passwords, ordered by decreasing probability.
Deriving an encryption key from a password is relatively slow (due to the iteration of the key derivation algorithm). Deriving keys for a few million passwords could take months. This would motivate an attacker to derive the keys from his most-likely-password list once, and store the results. With such a list, he can quickly try to decrypt with each key in his list, rather than spending months of compute time to derive keys again.
However, each bit of salt doubles the space required to store the derived key, and the time it takes to derive keys for each of his likely passwords. A few bytes of salt, and it quickly becomes infeasible to create and store such a list.
Salt is necessary to prevent pre-computation attacks.
An IV (or nonce with counter modes) makes the same plain text produce different cipher texts. The prevents an attacker from exploiting patterns in the plain text to garner information from a set of encrypted messages.
An initialization vector is necessary to hide patterns in messages.
One serves to enhance the security of the key, the other enhances the security of each message encrypted with that key. Both are necessary together.
First things first: Rijndael does not have a "password" in CBC mode. Rijndael in CBC mode takes a buffer to encrypt or decrypt, a key, and an IV.
A "salt" is typically used for encrypting passwords. The salt is added to the password that is encrypted and stored with the encrypted value. This prevents someone from building a dictionary of how all passwords encrypt---you need to build a dictionary of how all passwords encrypt for all salts. That was actually possible with the old Unix password encryption algorithm, which only used a 12-bit salt. (It increased the work factor by 4096). With a 128-bit salt it is not possible.
Someone can still do a brute-force attack on a specific password, of course, provided that they can retrieve the encrypted password.
However, you have an IV, which does pretty much the same thing that a Salt does. You don't need both. Or, rather, the IV is your salt.
BTW, these days we call "Rijndael" AES.
A salt is generally used when using a hash algorithm. Rijndael is not a hash, but a two-way encryption algorithm. Ergo, a salt is not necessarily needed for encrypting the data. That being said, a salted hash of a password may be used as the Key for encrypting data. For what you're looking for, you might wish to look at hybrid cryptosystems.
The Key should be considered private and not transmitted with your encrypted data while the IV may be transmitted with the encrypted data.

Should I generate a key from a hash for encryption?

I am currently currently using Rijndael 256-bit in CBC mode to encrypt some data which needs to be sent elsewhere. In order to enhance security, I'm taking a randomly generated SHA-256 hash and using a formula to chop off different parts it to use the encryption key and initialization vector (of course, the hash is sent with the data). The formula to generate the key and IV is fairly basic, and because the code is written in PHP, it's coded into a user-accessible page. What I'm wondering is: is this more or less safe than having one constant key and/or IV?
This is probably NOT the way you wish to go. In essence, it will take a good hacker not to long to figure out your mathematical formula for manipulating the HASH to generate your key and IV. Thus you are essentially sending the keys to the kingdom along with the kingdom itself.
Generally the way this type of operation is done, is to generate a session key (could be the same way you are doing it now), but use a public key encryption method to encrypt that session key. Then you use the public key encryption method to send the session key to the location your data is to be sent. The receiver has the public key and can encrypt the comm. channel session key.
Now both sides have the comm. channel session key and your REAL data can be encrypted using this key as the session key has not been sent in the clear.
Rijindael is an example of a symmetric crypto algorithm, where public key crypto algorithms are asymmetric. Examples of public key crypto algorithms are RSA, ECDSA (Crypto), etc....
On generating short-use keys. Have a long term key. Agree a date format with the receiver. Each day concatenate your long term key with the day's date and hash it with SHA-256 to generate a day key for use on that date only:
dayKey <- SHA256("my very secret long term key" + "2012-06-27")
The receiver will have all the information they need to generate exactly the same key at their end. Any attacker will know the date, but will not know the long term key.
You will need to agree protocols for around midnight and a few other details.
Change the long term key every month or two, depending on the amount of encrypted data you are passing. The more data you pass, the more often you need to change the long term key.

AES init vector

Do I have provide AES key + IV for someone to be able to decrypt encrypted data?
Does that increase key length from 128 bit to 256 bits?
Yes, both the key and the IV are needed to decrypt something. Generally, the key should be exchanged using a secure channel or key exchange mechanism. The IV can be transmitted along with the encrypted data in plain text. An IV should ideally be used only once. The main motivation behind using a changing IV is that encrypting the same thing twice should not result in the same ciphertext both times, because this can allow an attacker to draw conclusions about the data encrypted.

Is there two key symetric commutative encryption function?

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
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):
Alice and Bob perform an authenticated Diffie-Hellman exchange to produce the IV. This IV is then sent to Charlie.
Alice computes digest(key0, IV + ctr) for ctr = 0...number-of-ciphertext-blocks, and sends the result KS_A to Charlie
Bob computes digest(key1, IV + ctr) for ctr = 0...number-of-ciphertext-blocks, and sends the result KS_B to Charlie
Charlie computes KS_A XOR KS_B XOR plaintext, and sends the resulting ciphertext to both Alice and Bob.
Alice and Bob each sign a tuple (IV, hash(ciphertext), description-of-encrypted-data). This is attached to the ciphertext.
Later, to decrypt:
Charlie (performing the decryption) sends the signed (IV, hash(ciphertext)) tuples to each of Alice and Bob, as well as the ciphertext.
Alice verifies his signed tuple, computes KS_A, and sends ciphertext XOR KS_A = D_A to Charlie
Bob verifies his signed tuple, computes KS_B, and sends ciphertext XOR KS_B = D_B to Charlie
Charlie computes KS = D_A XOR D_B = KS_A XOR KS_B
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.
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.
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.

Is there a way to alter a public key in a way that the decryption can still be done with the private key after some alteration?

In an asymetric encryption scheme, I was wondering if it's possible to achieve the following:
Bob sends to Alice his public key
Alice alters Bob's public key and encrypt some document with it
Alice sends the encrypted document to Bob
Bob retrieve the document but can't decrypt it with his private key
Later, Alice sends some additional information (probably related to the method she used to alter Bob's public key) to Bob
Bob uses this additional information to modify his private key and successfully decrypt the document
Anyone?
I am assuming RSA for the keys generation, encryption and decryption but if it's easier to do with another scheme feel free to comment.
(I assume you talk about RSA.)
Yes it is possible, but not 100%.
The public key is a part of the private key. It contains the modulus and the exponent of the key.
You can completely forget changing the modulus, because you would have to generate a new rsa keypair, which is the same problem as the one we are trying to solve.
But it is possible to change the exponent. You can select any (prime) number between 1 and your exponent as the new exponent and hope that it is coprime with the totient. Without knowing the totient it's impossible to select always a correct exponent. To find out the totient you would have to know the prime factors of the key, which means that you would have to break the key (have fun!).
So, it's actually impossible to have a 100% percent working method to do that, at least not while knowing only the public key.
If you need more information about the theory check here
I hope my idea works.
Let us assume that (e,d,n) is a tuple of the RSA public exponent. The RSA private exponent and the RSA modulus n :
Select a prime number, say p, between 1 and a 256 bit integer.
To encrypt a message m, compute the new public exponent as e*p and the ciphertext as:
c= m^{e*p} mod n.
To decrypt, the receiver should know the prime p, so you send this p later to him, with this he computes
(1) P = p^{-1} mod phi(n)
and
(2) m^e=c^{P} mod n
and
finally m=(m^e)^d mod n. This works as the receiver knows phi(n).
By the way, where can we use this? Is there any application you have in mind for this?
As silky implies in his answer, the way in which RSA is usually used to encrypt a document is in combination with a symmetric algorithm, like AES. A secure random key is generated for the AES algorithm, the documented is encrypted with that AES key, and the AES key is encrypted with the recipient's public key. Both parts are supplied to the recipient.
You can adapt this to your situation simply by sending only the document encrypted with the AES key in the first step, and withholding the AES key encrypted with the recipient's public key until the second step. The first part will be on the order of the original file size, and the second part will be a small, constant size (on the order of the RSA key size).
Hmm, interesting.
You're referring to RSA, I assume?
FYI, RSA isn't actually used to encrypt documents. It's used to exchange keys (keys for a symmetric algorithm, like AES).
So what you're really talking about is an approach that changes the keys.
Technically (mathmatically) if you put a different number in, you'll get a different number out. So that's not an issue; changing the public key in some fashion will (assuming you convince your RSA implementation to use it, or prepare an appropriately different number) result in a different symmetric key, thus an undecryptable document by Bob (because he'll expect a different key).
Really, though, I'm not so sure you care about this. It's a fairly useless thing to do. Perhaps, however, you're actually interested in Key Splitting (or "Secret Sharing" as wikipedia seems to call it).
HTH. I'm by no means an expert.

Resources