Weak Key for DES in .NET Core

Viewed 290

I need to perform a DES encryption and decryption operation using a key of zeros. I'm getting this exception:

Specified key is a known weak key for 'DES' and cannot be used.

Here is my code:

public byte[] EncryptData(byte[] data, int offset, int length, byte[] key, byte[] iv)
    {
        try
        {
            using (var cryptoProvider = new DESCryptoServiceProvider())
            {
                cryptoProvider.Key = key;
                cryptoProvider.IV = iv;
                cryptoProvider.Mode = CipherMode.ECB;
                cryptoProvider.Padding = PaddingMode.None;

                ICryptoTransform encryptor = cryptoProvider.CreateEncryptor();

                // Create MemoryStream    
                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
                    {
                        cs.Write(data, offset, length);
                    }
                    return ms.ToArray();
                }
            }
        }
        catch (Exception e)
        {
            return null;
        }
    }

I've seen that this can be overcome by using this code:

MethodInfo mi = _des.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
object[] Par = { _k, _des.Mode, _des.IV, _des.FeedbackSize, 0 };
ICryptoTransform encryptor = mi.Invoke(_des, Par) as ICryptoTransform;

but this only works in .Net Framework. In .NET Core there is no _NewEncryptor method, so it returns null.

  • I can't override the Key property behavior because DESCryptoServiceProvider is sealed.
  • I can't extend DES because the actual implementation is in the DESCryptoServiceProvider class

And from the source code:

 public override byte[] Key
    {
        get
        {
            byte[] key = base.Key;
            while (IsWeakKey(key) || IsSemiWeakKey(key))
            {
                GenerateKey();
                key = base.Key;
            }
            return key;
        }
        set
        {
            if (value == null)
                throw new ArgumentNullException(nameof(value));

            if (!(value.Length * 8).IsLegalSize(s_legalKeySizes))
                throw new ArgumentException(SR.Cryptography_InvalidKeySize);

            if (IsWeakKey(value))
                throw new CryptographicException(SR.Cryptography_InvalidKey_Weak, "DES");

            if (IsSemiWeakKey(value))
                throw new CryptographicException(SR.Cryptography_InvalidKey_SemiWeak, "DES");

            base.Key = value;
        }
    }

because of the behavior of get Key this code

var keyField = cryptoProvider.GetType().GetField("KeyValue", BindingFlags.NonPublic | BindingFlags.Instance);
                keyField.SetValue(cryptoProvider, key);

can't help too and i am out of options :|. Is there another way to overcome weak key in .NET Core?

1 Answers

I've found a way to overcome weak key by using a library (BouncyCastle.NetCore). If someone needs the code, here it is:

public byte[] EncryptData(byte[] data, int offset, int length, byte[] key, byte[] iv)
    {
        try
        {
            var desEngine = new DesEngine();
            var cbcBlockCipher = new CbcBlockCipher(desEngine);
            var bufferedBlockCipher = new BufferedBlockCipher(cbcBlockCipher);

            bufferedBlockCipher.Init(true, new ParametersWithIV(new KeyParameter(key),iv));

            var cipherData = new byte[bufferedBlockCipher.GetOutputSize(length - offset)];

            var outputLength = bufferedBlockCipher.ProcessBytes(data, offset, length, cipherData, 0);

            bufferedBlockCipher.DoFinal(cipherData, outputLength);

            return cipherData;
        }
        catch (Exception e)
        {
            return null;
        }
    }
Related