首页 文章

DES解密仅在密钥为0时才起作用

提问于
浏览
2

我在这里遇到一种奇怪的行为 . 每当我将DES密钥设置为0时,解密就会起作用,但是如果我将密钥设置为其他任何东西,那么解密将返回一个不可读的字符串:

Main method:

static void Main(string[] args)     
{
    //Decryption works!
    byte[] key0 = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; 

    //Decryption doesn't work!
    byte[] key1 = new byte[] { 0x00, 0xFF, 0xFF, 0xAF, 0x12, 0x14, 0x15, 0xEC };

    SimpleDES des = new SimpleDES(key1);
    byte[] data = Encoding.ASCII.GetBytes("12345678");
    byte[] encrypted = des.Encrypt(data);

    byte[] decrypted = des.Decrypt(encrypted);
    string decryptedString = Encoding.ASCII.GetString(decrypted);

    //Only shows original plaintext if key0 is used.
    Console.WriteLine("Decrypted string: {0}", decryptedString);
    Console.ReadKey();
}

SimpleDES class:

public class SimpleDES
{
    private readonly byte[] IV = new byte[8] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    private byte[] mKey;
    private DESCryptoServiceProvider des;

    public SimpleDES(byte[] aKey)
    {
        if (aKey.Length != 8)
            throw new Exception("Key size must be 8 bytes");
        mKey = aKey;
        des = new DESCryptoServiceProvider();
        des.BlockSize = 64;
        des.KeySize = 64;
        des.Padding = PaddingMode.None;
    }

    public byte[] Encrypt(byte[] data)
    {
        if (data.Length != 8)
            throw new Exception("Data size must be 8 bytes");

        ICryptoTransform encryptor = des.CreateWeakEncryptor(mKey, IV);
        return encryptor.TransformFinalBlock(data, 0, data.Length);
    }

    public byte[] Decrypt(byte[] data)
    {
        if (data.Length != 8)
            throw new Exception("Data size must be 8 bytes");
        ICryptoTransform decryptor = des.CreateWeakDecryptor(mKey, IV);
        return decryptor.TransformFinalBlock(data, 0, data.Length);
    }
}

DESCryptoExtensions class:

public static class DESCryptoExtensions
{
    public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
    {
        // reflective way of doing what CreateEncryptor() does, bypassing the check for weak keys
        MethodInfo mi = cryptoProvider.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
        object[] Par = { key, cryptoProvider.Mode, iv, cryptoProvider.FeedbackSize, 0 };
        ICryptoTransform trans = mi.Invoke(cryptoProvider, Par) as ICryptoTransform;
        return trans;
    }

    public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider)
    {
        return CreateWeakEncryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
    }

    public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
    {
        return CreateWeakEncryptor(cryptoProvider, key, iv);
    }

    public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider)
    {
        return CreateWeakDecryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
    }
}

key0 output:
enter image description here
key1 output:
enter image description here

1 回答

  • 2

    您忘记了 _NewEncryptor (最后一个)中的 CryptoAPITransformMode 参数 . 你把它"fixed"设为0,但它可以是0或1( EncryptDecrypt ) . 它是内部的,但最后传递 int 是可以的 .

    public static class DESCryptoExtensions
    {
        // Mode = 0 encrypt, 1 decrypt
        public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv, int mode = 0)
        {
            // reflective way of doing what CreateEncryptor() does, bypassing the check for weak keys
            MethodInfo mi = cryptoProvider.GetType().GetMethod("_NewEncryptor", BindingFlags.NonPublic | BindingFlags.Instance);
            object[] Par = { key, cryptoProvider.Mode, iv, cryptoProvider.FeedbackSize, mode };
            ICryptoTransform trans = mi.Invoke(cryptoProvider, Par) as ICryptoTransform;
            return trans;
        }
    
        public static ICryptoTransform CreateWeakEncryptor(this DESCryptoServiceProvider cryptoProvider)
        {
            return CreateWeakEncryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
        }
    
        public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider, byte[] key, byte[] iv)
        {
            return CreateWeakEncryptor(cryptoProvider, key, iv, 1);
        }
    
        public static ICryptoTransform CreateWeakDecryptor(this DESCryptoServiceProvider cryptoProvider)
        {
            return CreateWeakDecryptor(cryptoProvider, cryptoProvider.Key, cryptoProvider.IV);
        }
    }
    

相关问题