2

我正在通过.Net开发一个mvc应用程序,以保护我的敏感信息,例如web.config中的信息我有两个使用Triple DES加密和解密信息的函数,但是我对此并不陌生并成功达到在朋友的帮助下。

加密功能工作正常并返回正确的字符串但是当我尝试解密我得到的相同字符串时

Exception Details: System.Security.Cryptography.CryptographicException: Bad Data.

解密函数这一行的错误:

Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);

我试图以我作为注释代码包含的几种方式来解决它,但他们没有帮助,请帮助我解决这个问题。

public static string Encrypt(string Message, string Passphrase)
    {
        byte[] Results;
        System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
        MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
        byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase)));
        TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
        TDESAlgorithm.Key = TDESKey;
        TDESAlgorithm.Mode = CipherMode.ECB;
        TDESAlgorithm.Padding = PaddingMode.PKCS7;
        byte[] DataToEncrypt = UTF8.GetBytes(Message);
        try
        {
            ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
            Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
        }
        finally
        {
            TDESAlgorithm.Clear();
            HashProvider.Clear();
        }
        return Convert.ToBase64String(Results);
        //return Encoding.UTF8.GetString(Results);

    }

    public static string Decrypt(string Message, string Passphrase)
    {
        byte[] Results;
        System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
        MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
        byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase)));
        TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
        TDESAlgorithm.Key = TDESKey;
        TDESAlgorithm.Mode = CipherMode.ECB;
        TDESAlgorithm.Padding = PaddingMode.PKCS7;
        try
        {
            byte[] DataToDecrypt = Convert.FromBase64String(Message);
            //byte[] DataToDecrypt = UTF8.GetBytes(Message);
            //byte[] DataToDecrypt = Encoding.UTF8.GetBytes(Message);
            ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
            Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length); // << ERROR is here.
        }
        finally
        {
            TDESAlgorithm.Clear();
            HashProvider.Clear();
        }
        return UTF8.GetString(Results);
    }
4

2 回答 2

7

TripleDES 算法指定了一个 IV(初始化向量),用于确保使用相同密钥对相同数据进行重复加密会产生不同的密文。要成功解密,解密过程中必须使用与加密期间相同的 IV。

由于您当前TDESAlgorithm.IV在执行加密时未指定 IV ( ),因此算法将其设置为随机值。该算法还将解密期间使用的 IV 设置为随机值(但与加密中使用的不同),因此解密过程失败。

要更正此问题,您可以使用以下方法(请注意,在加密阶段随机生成的 IV 是从Encrypt方法输出并传递给Decrypt方法):

public static string Encrypt(string Message, string Passphrase, out byte[] iv)
{
    byte[] Results;
    System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
    MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
    byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase)));
    TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
    TDESAlgorithm.Key = TDESKey;
    TDESAlgorithm.Mode = CipherMode.ECB;
    TDESAlgorithm.Padding = PaddingMode.PKCS7;
    // Capture the randomly generated IV
    iv = TDESAlgorithm.IV;
    byte[] DataToEncrypt = UTF8.GetBytes(Message);
    try
    {
        ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
        Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length);
    }
    finally
    {
        TDESAlgorithm.Clear();
        HashProvider.Clear();
    }
    return Convert.ToBase64String(Results);
    //return Encoding.UTF8.GetString(Results);
}

public static string Decrypt(string Message, string Passphrase, byte[] iv)
{
    byte[] Results;
    System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
    MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
    byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(GetSHA256String(Passphrase)));
    TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
    TDESAlgorithm.Key = TDESKey;
    // Apply the same IV used during encryption
    TDESAlgorithm.IV = iv;
    TDESAlgorithm.Mode = CipherMode.ECB;
    TDESAlgorithm.Padding = PaddingMode.PKCS7;
    try
    {
        byte[] DataToDecrypt = Convert.FromBase64String(Message);
        //byte[] DataToDecrypt = UTF8.GetBytes(Message);
        //byte[] DataToDecrypt = Encoding.UTF8.GetBytes(Message);
        ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
        Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length); // << ERROR is here.
    }
    finally
    {
        TDESAlgorithm.Clear();
        HashProvider.Clear();
    }
    return UTF8.GetString(Results);
}

请注意,如果您以后要成功解密数据,则需要将 IV 与密文一起存储。

于 2012-05-28T10:25:53.617 回答
0

我最近遇到了这个问题。一个空值已传递给Decrypt(). 如果(要解密的数据)为空,则TransformFinalBlock()(内部Decrypt())抛出错误数据异常。Message

因此,请在调用之前为要解密的数据添加一个空/空检查Decrypt()

于 2018-04-11T08:48:11.117 回答