加密结构,错误数据错误,是什么原因造成的?

发布于 2025-01-06 21:03:52 字数 3983 浏览 1 评论 0原文

我不确定我做错了什么,加密似乎有效,但是当你尝试反序列化时解密时会说坏数据,不知道我做错了什么。我是加密方面的新手,所以如果它真的很简单,我很抱歉。

    public byte[] Serialize(object obj, string key)
    {
        byte[] returnBytes;
        using (MemoryStream memory = new MemoryStream())
        {
            UTF8Encoding UTF8 = new UTF8Encoding();
            TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] pass = provider.ComputeHash(UTF8.GetBytes(key));
            crypt.Key = pass;
            crypt.Mode = CipherMode.ECB;
            crypt.Padding = PaddingMode.PKCS7;
            using (CryptoStream stream = new CryptoStream(memory, crypt.CreateEncryptor(), CryptoStreamMode.Write))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
                stream.Close();
                memory.Close();
            }

            returnBytes = memory.ToArray();
        }

        return returnBytes;
    }
    public object Deserialize(byte[] inBytes, string key)
    {
        object returnObj;
        using (MemoryStream memory = new MemoryStream())
        {
            UTF8Encoding UTF8 = new UTF8Encoding();
            TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] pass = provider.ComputeHash(UTF8.GetBytes(key));
            crypt.Key = pass;
            crypt.Mode = CipherMode.ECB;
            crypt.Padding = PaddingMode.PKCS7;
            using (CryptoStream stream = new CryptoStream(memory, crypt.CreateDecryptor(), CryptoStreamMode.Read))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                returnObj = formatter.Deserialize(stream);
                stream.Close();
                memory.Close();
            }
            return returnObj;
        }

    }

我不久前编写的这段代码适用于字符串

        public string encrypt(string message, string password)
        {
            byte[] result;
            UTF8Encoding UTF8 = new UTF8Encoding();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] key = provider.ComputeHash(UTF8.GetBytes(password));
            TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider();
            algorithm.Key = key;
            algorithm.Mode = CipherMode.ECB;
            algorithm.Padding = PaddingMode.PKCS7;
            byte[] data = UTF8.GetBytes(message);
            try
            {
                ICryptoTransform encryptor = algorithm.CreateEncryptor();
                result = encryptor.TransformFinalBlock(data, 0, data.Length);
            }
            finally
            {
                algorithm.Clear();
                provider.Clear();
            }
            return Convert.ToBase64String(result);
        }
        public string decrypt(string message, string passsword)
        {
            byte[] result;
            UTF8Encoding UTF8 = new UTF8Encoding();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] key = provider.ComputeHash(UTF8.GetBytes(passsword));
            TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider();
            algorithm.Key = key;
            algorithm.Mode = CipherMode.ECB;
            algorithm.Padding = PaddingMode.PKCS7;
            byte[] data = Convert.FromBase64String(message);
            try
            {
                ICryptoTransform decryptor = algorithm.CreateDecryptor();
                result = decryptor.TransformFinalBlock(data, 0, data.Length);
            }
            finally
            {
                algorithm.Clear();
                provider.Clear();
            }
            return UTF8.GetString(result);
        }

I'm not sure what I'm doing wrong, the encryption it seems to work but when you get to the decryption says bad data when trying to deserialize it, not sure what I'm doing wrong. I'm new at doing encryption so if it's something really simple I'm sorry.

    public byte[] Serialize(object obj, string key)
    {
        byte[] returnBytes;
        using (MemoryStream memory = new MemoryStream())
        {
            UTF8Encoding UTF8 = new UTF8Encoding();
            TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] pass = provider.ComputeHash(UTF8.GetBytes(key));
            crypt.Key = pass;
            crypt.Mode = CipherMode.ECB;
            crypt.Padding = PaddingMode.PKCS7;
            using (CryptoStream stream = new CryptoStream(memory, crypt.CreateEncryptor(), CryptoStreamMode.Write))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
                stream.Close();
                memory.Close();
            }

            returnBytes = memory.ToArray();
        }

        return returnBytes;
    }
    public object Deserialize(byte[] inBytes, string key)
    {
        object returnObj;
        using (MemoryStream memory = new MemoryStream())
        {
            UTF8Encoding UTF8 = new UTF8Encoding();
            TripleDESCryptoServiceProvider crypt = new TripleDESCryptoServiceProvider();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] pass = provider.ComputeHash(UTF8.GetBytes(key));
            crypt.Key = pass;
            crypt.Mode = CipherMode.ECB;
            crypt.Padding = PaddingMode.PKCS7;
            using (CryptoStream stream = new CryptoStream(memory, crypt.CreateDecryptor(), CryptoStreamMode.Read))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                returnObj = formatter.Deserialize(stream);
                stream.Close();
                memory.Close();
            }
            return returnObj;
        }

    }

This code i did a while back works on strings

        public string encrypt(string message, string password)
        {
            byte[] result;
            UTF8Encoding UTF8 = new UTF8Encoding();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] key = provider.ComputeHash(UTF8.GetBytes(password));
            TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider();
            algorithm.Key = key;
            algorithm.Mode = CipherMode.ECB;
            algorithm.Padding = PaddingMode.PKCS7;
            byte[] data = UTF8.GetBytes(message);
            try
            {
                ICryptoTransform encryptor = algorithm.CreateEncryptor();
                result = encryptor.TransformFinalBlock(data, 0, data.Length);
            }
            finally
            {
                algorithm.Clear();
                provider.Clear();
            }
            return Convert.ToBase64String(result);
        }
        public string decrypt(string message, string passsword)
        {
            byte[] result;
            UTF8Encoding UTF8 = new UTF8Encoding();
            MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider();
            byte[] key = provider.ComputeHash(UTF8.GetBytes(passsword));
            TripleDESCryptoServiceProvider algorithm = new TripleDESCryptoServiceProvider();
            algorithm.Key = key;
            algorithm.Mode = CipherMode.ECB;
            algorithm.Padding = PaddingMode.PKCS7;
            byte[] data = Convert.FromBase64String(message);
            try
            {
                ICryptoTransform decryptor = algorithm.CreateDecryptor();
                result = decryptor.TransformFinalBlock(data, 0, data.Length);
            }
            finally
            {
                algorithm.Clear();
                provider.Clear();
            }
            return UTF8.GetString(result);
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

演多会厌 2025-01-13 21:03:52

您没有设置 IV< crypt 的 /code>属性,因此每次都以随机值开始。解密时需要将其设置为与加密时相同的值 - 就像用于散列的盐一样。编辑:鉴于 ECB 的工作方式,看起来 IV 可能会被忽略,这就是为什么您之前的代码可以在不存储它的情况下工作。

编辑:虽然非欧洲央行肯定需要 IV 部分,但这还不够。我不确定剩下的问题是什么,但:

  • 不推荐使用 ECB 密码模式 - 有什么理由使用它?
  • 您很可能最终会因填充而遇到问题;我不知道 BinaryFormatter 是否会自动为您处理该问题,但值得研究一下。

编辑:Doh - 我已经解决了更大的问题;根据 Elian 的评论,您确实应该使用 inBytes 。目前您完全忽略了密文 - 这没有工作的机会!

这是一个完整的程序,显示了整个过程:

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;

class Test
{
    static void Main()
    {
        byte[] data = Serialize("Some arbitrary test data", "pass");
        object x = Deserialize(data, "pass");
        Console.WriteLine(x);
    }

    private static SymmetricAlgorithm CreateCryptoServiceProvider(string key)
    {
        byte[] passwordHash;
        using (MD5 md5 = MD5.Create())
        {
            // It's not clear why you're taking the hash of the password...
            passwordHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key));
        }
        var crypt = new TripleDESCryptoServiceProvider();
        crypt.Key = passwordHash;
        crypt.Mode = CipherMode.CBC; // This is the default anyway - can remove
        crypt.Padding = PaddingMode.PKCS7; // Ditto
        // Fix this to use a randomly generated one and store it for real code.
        crypt.IV = new byte[crypt.BlockSize / 8];
        return crypt;
    }

    public static byte[] Serialize(object obj, string key)
    {
        var provider = CreateCryptoServiceProvider(key);

        using (MemoryStream memory = new MemoryStream())
        {
            using (CryptoStream stream = new CryptoStream(
                memory, provider.CreateEncryptor(), CryptoStreamMode.Write))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
            }
            return memory.ToArray();
        }
    }

    public static object Deserialize(byte[] inBytes, string key)
    {
        var provider = CreateCryptoServiceProvider(key);

        using (MemoryStream memory = new MemoryStream(inBytes))
        {
            using (CryptoStream stream = new CryptoStream(
                memory, provider.CreateDecryptor(), CryptoStreamMode.Read))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                return formatter.Deserialize(stream);
            }
        }
    }

}

You're not setting the IV property of crypt, so it's starting off as a random value each time. You need to set it to the same value when decrypting as when encrypting - like a salt for hashing. EDIT: Given the way ECB works, it looks like the IV may be ignored, which is why your previous code worked without storing it.

EDIT: While the IV part is certainly required for non-ECB, it's not enough. I'm not sure what the rest of the problem is, although:

  • The ECB cipher mode isn't recommended - any reason for using it?
  • You may well end up running into problems due to padding; I don't know if BinaryFormatter handles that for you automatically, but it's worth looking into.

EDIT: Doh - I've worked out the bigger problem; you should indeed be using inBytes, as per Elian's comment. Currently you're completely ignoring the cipher-text - that's got no chance of working!

Here's a complete program showing the whole thing hanging together:

using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
using System.Runtime.Serialization.Formatters.Binary;

class Test
{
    static void Main()
    {
        byte[] data = Serialize("Some arbitrary test data", "pass");
        object x = Deserialize(data, "pass");
        Console.WriteLine(x);
    }

    private static SymmetricAlgorithm CreateCryptoServiceProvider(string key)
    {
        byte[] passwordHash;
        using (MD5 md5 = MD5.Create())
        {
            // It's not clear why you're taking the hash of the password...
            passwordHash = md5.ComputeHash(Encoding.UTF8.GetBytes(key));
        }
        var crypt = new TripleDESCryptoServiceProvider();
        crypt.Key = passwordHash;
        crypt.Mode = CipherMode.CBC; // This is the default anyway - can remove
        crypt.Padding = PaddingMode.PKCS7; // Ditto
        // Fix this to use a randomly generated one and store it for real code.
        crypt.IV = new byte[crypt.BlockSize / 8];
        return crypt;
    }

    public static byte[] Serialize(object obj, string key)
    {
        var provider = CreateCryptoServiceProvider(key);

        using (MemoryStream memory = new MemoryStream())
        {
            using (CryptoStream stream = new CryptoStream(
                memory, provider.CreateEncryptor(), CryptoStreamMode.Write))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                formatter.Serialize(stream, obj);
            }
            return memory.ToArray();
        }
    }

    public static object Deserialize(byte[] inBytes, string key)
    {
        var provider = CreateCryptoServiceProvider(key);

        using (MemoryStream memory = new MemoryStream(inBytes))
        {
            using (CryptoStream stream = new CryptoStream(
                memory, provider.CreateDecryptor(), CryptoStreamMode.Read))
            {
                BinaryFormatter formatter = new BinaryFormatter();
                return formatter.Deserialize(stream);
            }
        }
    }

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文