.net - 使用 Triple DES 解密信息时出现错误数据

标签 .net encryption cryptography 3des tripledes

我正在 .Net 上开发一个 mvc 应用程序,以保护我的敏感信息,例如 web.config 中的信息,我有两个使用 Triple DES 加密和解密信息的函数,但是我是新手在 friend 的帮助下成功到达。

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

异常详细信息:System.Security.Cryptography.CryptographicException:错误数据。

解密函数这一行出错:

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

最佳答案

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

由于您当前在执行加密时未指定 IV (TDESAlgorithm.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 与密文一起存储。

关于.net - 使用 Triple DES 解密信息时出现错误数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10781007/

相关文章:

.net - 为什么点符号在此正则表达式中不起作用?

asp.net - Gridview 将当前行与上一行进行比较

c# - EnumResourceNames 问题 - 未知错误

java - 从 pkcs12 和文本加密中提取私钥

c# - 如何从 'Guid' 返回 'Nullable<Guid>' ?

Flutter - 如何保护视频的安全,使其只能在我的应用程序中播放?

javascript - 在 Node.js : UnhandledPromiseRejectionWarning: Error: bad public key size 中使用 libsodium 进行 GitHub API secret 加密

c# - 解密从 PHP 服务接收到的 AES 缓冲区

javascript - 使用 RSA 技术在 JavaScript 中加密字符串并在 PHP 中解密

javascript - 使用 Node 的加密库创建自签名证书?