首页 > 解决方案 > .NET Core 中 DES 的弱键

问题描述

我需要使用零密钥执行 DES 加密和解密操作。我得到了这个例外:

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

这是我的代码:

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;
        }
    }

我已经看到可以通过使用以下代码来克服这个问题:

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;

但这仅适用于.Net Framework. 在 .NET Core 中没有_NewEncryptor方法,因此它返回 null。

从源代码:

 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;
        }
    }

因为 get Key 这个代码的行为

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

也无能为力,我没有选择:|。还有另一种方法可以克服 .NET Core 中的弱键吗?

标签: c#encryption.net-core

解决方案


我找到了一种通过使用库(BouncyCastle.NetCore)来克服弱键的方法。如果有人需要代码,这里是:

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;
        }
    }

推荐阅读