Why does any length key work for RijndaelManaged?
Asked Answered
Q

1

3

Regarding the method...

RijndaelManaged.CreateDecryptor Method (Byte[], Byte[])

Here it says about the first parameter...

The secret key to be used for the symmetric algorithm. The key size must be 128, 192, or 256 bits.

But I can set the key to be any length string...

var key = Encoding.UTF8.GetBytes("whetever...");

Why isn't it more fussy about the length of the byte array? And how does it determine which of the three key lengths to be used?

Quality answered 17/12, 2015 at 20:17 Comment(10)
But it is always best to provide the full length of the key and iv, don't depend on padding.Cedillo
It is usually a bad idea to use a string for a key, it significantly weakens your protection. Use a "Key derivation function" like Rfc2898DeriveBytes, you pass the password + a salt in to that and it lets you get a random byte[] out you can feed in to the key. The thing it does is it will give you the same byte[] for the same password and salt every time.Thomism
But isn't the password a string? A where would I store the salt? Aren't I already achieving the same thing with an initialisation vector (the second parameter)?Quality
The salt and IV could be the same value. Normally you have the Salt/IV stored along with the encrypted data, it is not considered "secret" information, for a file you put it in some kind of "header", for a database record you add a column for it. The only important thing is they are randomly generated every time you encrypt a new message so you don't re-use values.Thomism
The point of using Rfc2898DeriveBytes is if you are using a string as the key I know there is a huge number of things I don't have to try because they generate strings that could not be typed. By making a attacker go through the derive bytes function first it slows the process down so you cant as easily brute force every string a person could type. You can control how much slowdown via the IterationCount parameter (you likely want to store that too in the header too), choose the largest number possible that does not bother your users. The bigger the number the safer you are from attack.Thomism
Could I instead use a base64 encoded string?Quality
.net? In fact I tried a super long key and it did not work. But I still seem to be able to vary the length of the string.Quality
Min is 8. Max is 16. So I suppose it uses the largest size key it can, where each character is 16 bits.Quality
Because Microsoft messed up the argument validation.Crossbeam
Related: What does RijndaelManaged encryption do with invalid key sizesCrossbeam
B
6

It isn't true that any key size works. Only a specific set of key sizes should be allowed.

The LegalKeySizes sizes property of RijndaelManaged actually reports the following values:

MinSize = 128
MaxSize = 256
SkipSize = 64

Which should indicate that only the AES key sizes are supported: 128, 192 and of course 256. This basically means that RijndaelManaged does not fully implement Rijndael, which also allows 160 and 224 bit as key sizes. Actually, I don't think it allows 160 and 224 bit for the block size either.

Now your question raised some question marks with me, so I decided to look which key sizes were actually accepted without raising an exception, and I got the following surprising result:

8, 9, 10, 11, 12, 13, 14, 15, 16, 24, 32

or, in bits instead of bytes:

64, 72, 80, 88, 96, 104, 112, 120, 128, 192, 256

So RijndaelManaged seems to accept more key sizes than specified, and these additional key sizes are below the minimum length specified by the class and the Rijndael algorithm.

Now lets encrypt something with these invalid key sizes:

064 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
072 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
080 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
088 : 1903b797b48ce006e618cb605d356981cc9b231195420010916e449037d3ac5b
096 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
104 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
112 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
120 : 4002ae70943dafdec10d4fbe2f97dc95b0a61e7412277197623b6d3d3e0da31c
128 : 66e94bd4ef8a2c3b884cfa59ca342b2e9434dec2d00fdac765f00c0c11628cd1
192 : aae06992acbf52a3e8f4a96ec9300bd71045be567103016ac50b21b86fc5457e
256 : dc95c078a2408989ad48a21492842087f3c003ddc4a7b8a94baedffc3d214c38

Note: for those interested: CBC with key consisting of all zero's, plaintext and IV are just 16 bytes set to zero too. Testing was performed on Windows 10:

OS: Microsoft Windows NT 10.0.10240.0, CLR : 4.0.30319.42000

So you just get some invalid, unspecified result for key sizes 64, 72, 80, 88, 96, 104, 112, 120. Looking at the code it basically uses only 8 bytes as key and leaves the other bytes set to zero for key sizes 8..11 and 12 bytes as key for key sizes 12..15. In that case the block size will be 128 bits, otherwise the block size will be the same as the key size. So the implementation actually strips one to three bytes from the end of the key before it is used for key sizes 72, 80, 88, 104, 112 and 120 bits.

So basically this seems a bug in the implementation. Basically you should not use RijndaelManaged outside the values returned by LegalKeySizes.


As already indicated, you should use Rfc2898DeriveBytes to convert a password to a key with a valid key size.

Beatriz answered 18/12, 2015 at 11:29 Comment(4)
I dug through that code a few months ago. From what I remember it pads the key to full 32 bit words and adjusts the key-schedule/number of rounds depending on the number of words.Crossbeam
Do you know the type of padding? It seems that only one size keys would be generated at the front end, so the adjustment of rounds / key schedule may not be required..Beatriz
Oh my god it doesn't pad, it strips the bytes.Beatriz
I don't remember the details, but I remember being horrified by the code. It might even have contained a buffer overflow for some key sizes (caught by the runtime checking array indices).Crossbeam

© 2022 - 2024 — McMap. All rights reserved.