【问题标题】:Getting Bad Data exception during decryption (using .Net Cryptography)解密期间出现错误数据异常(使用 .Net Cryptography)
【发布时间】:2014-03-15 11:48:29
【问题描述】:

我正在使用 TripleDESCryptoServiceProvider (.Net 2.0) 类中的对称 TripleDES 加密来加密文件的内容。 数据被完美加密,但在解密过程中会抛出 CryptographyException: Bad data


我正在使用当前日期时间的密钥和 .Net 类随机生成的值中的 IV。然后我将相同的密钥和 IV 传递给解密方法,但由于某种原因它失败了。
这是我的代码:

static void Main(string[] args){
    string fileName = "input.exe";
    string newFileName = fileName + "crypted.exe";
    byte[] iv;
    var fileToEncrypt = File.ReadAllBytes(fileName);
    var encryptionKey = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes(DateTime.Now.ToString("ddMMyyHmmss")));
    File.WriteAllBytes(newFileName, EncryptTripleDES(fileToEncrypt, encryptionKey, out iv));
    File.WriteAllBytes(fileName + "decrypted.exe", DecryptTripleDES(File.ReadAllBytes(newFileName), encryptionKey,iv));
}

public static byte[] EncryptTripleDES(byte[] dataToEncrypt, byte[] key, out byte[] iv){
    byte[] result;
    var tdes = new TripleDESCryptoServiceProvider { Key = key, KeySize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 };
    iv = tdes.IV;
    using(ICryptoTransform cTransform = tdes.CreateEncryptor()){
        result = cTransform.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
        tdes.Clear();
    }

    return result;
}

public static byte[] DecryptTripleDES(byte[] dataToDecrypt, byte[] key, byte[] iv){
    byte[] result;
    var tdes = new TripleDESCryptoServiceProvider { Key = key, KeySize = 128, Mode = CipherMode.CBC,IV = iv,Padding = PaddingMode.PKCS7 };

    using (ICryptoTransform cTransform = tdes.CreateDecryptor()){
        result = cTransform.TransformFinalBlock(dataToDecrypt, 0, dataToDecrypt.Length);
        tdes.Clear();
    }

    return result;
}



更新:
1. 我已经检查了传递的 IV 的值是否有效,并且与加密中使用的值相同。
2. 将填充更改为零或无不会引发异常,但数据未正确解密。结果和原来的不一样。

【问题讨论】:

  • 请注意,3DES 是您可以选择的最差算法,攻击者可以在您不注意的情况下修改您的加密数据。
  • 是的,我知道。出于某种秘密原因使用它:)
  • 使用当前时间的MD5总和也是不好的做法。密钥应由加密安全的随机数生成器生成,并针对 DES 弱密钥进行过滤。
  • 再次感谢,但目前我只是对解决方案感兴趣,稍后我会处理好的做法,我的用例略有不同,所有这些都无关紧要
  • 检查 EncryptTripleDES() 函数返回的 IV 以确保 IV 没有被 Clear() 函数清零。如果是,您需要在tdes 显式制作IV 字节数组的副本。

标签: c# .net encryption cryptography


【解决方案1】:

问题在于您使用初始化程序构造TripleDESCryptoServiceProviders 的方式。 Key 首先在初始化程序中设置,然后设置 KeySize,这会导致 Key 重置为新的(随机生成的)密钥,因此,您使用不同的加密和解密键(两者都不是您生成的key)。

您可以通过重新排序初始化程序来解决此问题,以便首先设置 KeySize,或者将 Key 的设置完全移到初始化程序之外以避免任何歧义:

public static byte[] EncryptTripleDES(byte[] dataToEncrypt, byte[] key, out byte[] iv){
    byte[] result;
    var tdes = new TripleDESCryptoServiceProvider { KeySize = 128, Mode = CipherMode.CBC, Padding = PaddingMode.PKCS7 };
    // Key explicitly set here, not in the initializer:
    tdes.Key = key;
    iv = tdes.IV;

    using(ICryptoTransform cTransform = tdes.CreateEncryptor()){
        result = cTransform.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length);
        tdes.Clear();
    }

    return result;
}

public static byte[] DecryptTripleDES(byte[] dataToDecrypt, byte[] key, byte[] iv){
    byte[] result;
    var tdes = new TripleDESCryptoServiceProvider { KeySize = 128, Mode = CipherMode.CBC,IV = iv,Padding = PaddingMode.PKCS7 };
    // Key explicitly set here, not in the initializer:
    tdes.Key = key;

    using (ICryptoTransform cTransform = tdes.CreateDecryptor()){
        result = cTransform.TransformFinalBlock(dataToDecrypt, 0, dataToDecrypt.Length);
        tdes.Clear();
    }

    return result;
}

【讨论】:

  • 哦,天哪.. 我永远找不到那个错误。很难找到的错误。但它现在工作正常,非常感谢。
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 2011-04-28
  • 2017-12-10
  • 2014-01-28
  • 2010-11-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多