AesManaged 实施在 Mono 下中断...?

发布于 2024-12-09 10:33:00 字数 2430 浏览 0 评论 0原文

我有一个程序在 Windows 和 .NET Framework 4 下运行得很好,但是在 Mono(内置于 MonoDevelop 2.6)下,Encrypt()Decrypt()函数似乎只工作了一半...

如果我在本地加密某些内容然后立即解密它(在 Mono 下),消息的前 10 个左右字符会被扰乱,但后面的任何内容看起来都完全有效!

加密函数如下:

    public byte[] Encrypt(string plainText)
    {
        DateTime now = DateTime.Now;
        string timeStamp = now.Millisecond.ToString("000") + "." + now.Second.ToString("00") + "." +
            now.Minute.ToString("00") + "." + now.Hour.ToString("00") + Constants.MessageSplitChar;
        plainText = plainText.Insert(0, timeStamp);

        MemoryStream memoryStream = new MemoryStream();

        lock (this.encryptor)
        {
            CryptoStream cryptoStream = new CryptoStream(memoryStream, this.encryptor, CryptoStreamMode.Write);
            StreamWriter writer = new StreamWriter(cryptoStream);
            try
            {
                writer.Write(plainText);
            }
            finally
            {
                writer.Close();
                cryptoStream.Close();
                memoryStream.Close();
            }
        }

        byte[] encryptedMessage = memoryStream.ToArray();
        return this.AppendArrays(BitConverter.GetBytes(encryptedMessage.Length), encryptedMessage);
    }

解密函数如下:

    public string Decrypt(byte[] cipherText)
    {
        try
        {
            string plainText = string.Empty;

            MemoryStream memoryStream = new MemoryStream(cipherText);

            lock (this.decryptor)
            {
                CryptoStream cryptoStream = new CryptoStream(memoryStream, this.decryptor, CryptoStreamMode.Read);
                StreamReader reader = new StreamReader(cryptoStream);

                try
                {
                    plainText = reader.ReadToEnd();
                    plainText = plainText.Substring(plainText.IndexOf("|") + 1);
                    plainText = plainText.TrimEnd("\0".ToCharArray());
                }
                finally
                {
                    reader.Close();
                    cryptoStream.Close();
                    memoryStream.Close();
                }
            }

            return plainText;
        }
        catch (Exception ex)
        {
            CMicroBingoServer.LogManager.Write(ex.ToString(), MessagePriority.Error);
            return "DECRYPTION_FAILED";
        }
    }

I've got a program that under Windows and .NET Framework 4 works perfectly well however, under Mono (built in MonoDevelop 2.6), the Encrypt() and Decrypt() function seem to only half work...

To the point at which if I locally encrypt something and then immediately decrypt it (under Mono), the first 10 or so characters of the message are scrambled jiberish, but anything following looks perfectly valid!

The Encrypt function is as follows:

    public byte[] Encrypt(string plainText)
    {
        DateTime now = DateTime.Now;
        string timeStamp = now.Millisecond.ToString("000") + "." + now.Second.ToString("00") + "." +
            now.Minute.ToString("00") + "." + now.Hour.ToString("00") + Constants.MessageSplitChar;
        plainText = plainText.Insert(0, timeStamp);

        MemoryStream memoryStream = new MemoryStream();

        lock (this.encryptor)
        {
            CryptoStream cryptoStream = new CryptoStream(memoryStream, this.encryptor, CryptoStreamMode.Write);
            StreamWriter writer = new StreamWriter(cryptoStream);
            try
            {
                writer.Write(plainText);
            }
            finally
            {
                writer.Close();
                cryptoStream.Close();
                memoryStream.Close();
            }
        }

        byte[] encryptedMessage = memoryStream.ToArray();
        return this.AppendArrays(BitConverter.GetBytes(encryptedMessage.Length), encryptedMessage);
    }

The Decrypt function is as follows:

    public string Decrypt(byte[] cipherText)
    {
        try
        {
            string plainText = string.Empty;

            MemoryStream memoryStream = new MemoryStream(cipherText);

            lock (this.decryptor)
            {
                CryptoStream cryptoStream = new CryptoStream(memoryStream, this.decryptor, CryptoStreamMode.Read);
                StreamReader reader = new StreamReader(cryptoStream);

                try
                {
                    plainText = reader.ReadToEnd();
                    plainText = plainText.Substring(plainText.IndexOf("|") + 1);
                    plainText = plainText.TrimEnd("\0".ToCharArray());
                }
                finally
                {
                    reader.Close();
                    cryptoStream.Close();
                    memoryStream.Close();
                }
            }

            return plainText;
        }
        catch (Exception ex)
        {
            CMicroBingoServer.LogManager.Write(ex.ToString(), MessagePriority.Error);
            return "DECRYPTION_FAILED";
        }
    }

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

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

发布评论

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

评论(2

时光无声 2024-12-16 10:33:00

您的代码不显示您的 decryptorencryptor 实例是如何创建的。

这可能是一个问题,因为如果您要重用该实例,则必须检查ICryptoTransform.CanReuseTransform。如果它返回false,那么您无法重复使用相同的加密器/解密器,并且必须创建新实例。

这一点更为重要,因为 Mono 和 .NET 对于某些算法有不同的默认值。但无论如何,跳过此检查意味着未来 .NET 框架中的任何更改(或通过配置文件,因为可以使用 CryptoConfig 来插入加密技术)可能有一天会破坏您的代码。

Your code does not show how your decryptor and encryptor instances are created.

This can be a problem because if you're reusing the instance then you must check ICryptoTransform.CanReuseTransform. If it returns false then you cannot reuse the same encryptor/decryptor and must create new instances.

That's even more important since Mono and .NET have different defaults for some algorithms. But in any case skipping this check means that any changes in future .NET framework (or via configuration files, since cryptography is pluggable using CryptoConfig) is likely to break your code someday.

忘你却要生生世世 2024-12-16 10:33:00

开头有多少个字符字节看似乱码可能很重要...如果第一个块是无意义的,但其余的都很好,那么可能是你的初始化向量在解密时不正确。

在最常见的块模式下,CBC在解密IV时仅影响第一个数据块的解密,因为此后它的密文充当后续块的IV。

您是否明确设置了用于加密和解密的 IV?如果没有的话,我会想象两者在处理未设置的 IV 时有不同的行为(例如,windows 使用全零,而 mono 生成随机 IV - 这将导致 windows 很好地解密,因为 IV 是相同的,而 mono 可能生成两个不同的 IV)用于加密和解密过程的 IV

我不太了解单声道的东西,无法研究确切的解决方案,但类似的事情似乎是可能的。

It may be important how many characters bytes at the beginning are seemingly gibberish... If the first block is coming out nonsense but the rest is fine then it could be that your initialization vector is not correct on decryption.

Under the most common block mode, CBC, when decrypting the IV only effects teh decryption of the first block of data since after that its the cipher text that acts as the IV for later blocks.

Are you explicitly setting IVs for encrypting and decrypting? If not then I would imagine that the two have different behaviours when dealing with unset IVs (eg windows uses all zeros and mono generates a random IV - this would cause windows to decrypt fine becuase the IV is the same whereas mono may be generating two different IVs for the encrypt and decrypt process.

I don't know mono stuff well enough to look into the exact solution but something along these lines seems likely.

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