AesManaged实现在Mono下中断

本文关键字:中断 Mono 实现 AesManaged | 更新日期: 2023-09-27 18:11:05

我有一个程序,在Windows和。net Framework 4下工作得很好,然而,在Mono下(内置在MonoDevelop 2.6), Encrypt()Decrypt()函数似乎只有一半的工作…

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

Encrypt功能如下:

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

AesManaged实现在Mono下中断

您的代码没有显示如何创建decryptorencryptor实例。

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

这更重要,因为Mono和。net对某些算法有不同的默认值。但是在任何情况下跳过这个检查都意味着在未来的。net框架中的任何更改(或者通过配置文件,因为加密是可以使用CryptoConfig插入的)都可能在某一天破坏你的代码。

开头有多少

字符字节似乎是乱码,这可能很重要…如果第一个块输出是无意义的,但其余的都很好,那么可能是你的初始化向量在解密时不正确。

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

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

我不太了解mono的东西,无法研究确切的解决方案,但似乎有一些类似的东西。