Search code examples
c#cryptographykeydestripledes

Decrypting TripleDES: Specified key is a known weak key and cannot be used


Why does this code return the weak key error?

static public byte[] TDESDecrypt(byte[] toDecrypt, byte[] key, CipherMode mode = CipherMode.ECB, PaddingMode padding = PaddingMode.None)
{
    TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
    tdes.Key = key;
    tdes.Mode = mode;
    tdes.Padding = padding;
    ICryptoTransform cTransform = tdes.CreateDecryptor();
    byte[] resultArray = cTransform.TransformFinalBlock(toDecrypt, 0, toDecrypt.Length);
    tdes.Clear();
    return resultArray;
}

When I try to execute the line "tdes.Key = key", I get the error

deriveSessionKeyIS System.Security.Cryptography.CryptographicException: Specified key is a known weak key for TripleDES and cannot be used

Why? The key I'm trying is random, but one of the tested keys, for example, is FB13347FE570DC4FFB13347FE570DC4F. Where is the problem?


Solution

  • You can read in wikipedia for example about what is the weak key in cryptography. For triple DES there is a method (TripleDES.IsWeakKey) which checks triple DES key for weakness. In you case, key FB13347FE570DC4FFB13347FE570DC4F is symmetric in a sense that first 8 bytes of it are exactly equal last 8 bytes. That means if you encrypt something with that key, and then encrypt that encrypted info one more time - you will restore original text (because of how this concrete encryption algorithm works), which is obviously dangerous.

    So in short .NET protects you from doing dangerous things resulting in cryptographic weakness. If you will use standard GenerateKey() function to generate key (or just don't set Key explicitly) - weak keys won't be generated.

    A bit more information about why that key is weak for triple DES. 3DES is named like this because it essentially uses 3 keys and applies pure DES encryption\decryption with those keys 3 times. Each key is 8 bytes long, so 3DES key size is 8*3 = 24 bytes. However, algorithm also allows for first and third keys to be the same, and as such allows to use 16-byte keys (like in your example). In that case first half of those 16-bytes are used as a third key. This option provides less security but is still viable.

    Now, when in your case first half and second half of your 16-bytes key are the same, so all three keys which will be used by 3DES are the same. Given that 3DES works like this:

    DES encrypt with 3rd(DES Decrypt with 2nd(DES Encrypt with 1st(plaintext)))
    

    You see that in your case you fall back to using simple DES, which defeats whole purpose of using 3DES in the first place.