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?