加密AesCryptoServiceProvider返回零字节数组?(Encrypt AesCryp

2019-09-26 13:27发布

我使用AesCryptoServiceProvider到加密某些文件配置时遇到错误。 摘要代码如下

private static byte[] secretKey =     {
                                                        (byte)0x63, (byte)0x23, (byte)0xdf, (byte)0x2a,
                                                        (byte)0x59, (byte)0x1a, (byte)0xac, (byte)0xcc,
                                                        (byte)0x50, (byte)0xfa, (byte)0x0d, (byte)0xcc,
                                                        (byte)0xff, (byte)0xfd, (byte)0xda, (byte)0xf0                                           
                                                    };                          

private static byte[] iv = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

public static byte[] EncryptStringToBytes(String plainText, byte[] secretKey, byte[] IV)
{
    try
    {
        // Check arguments. 
        if (plainText == null || plainText.Length <= 0)
            throw new ArgumentNullException("plainText");
        if (secretKey == null || secretKey.Length <= 0)
            throw new ArgumentNullException("secretKey");
        if (IV == null || IV.Length <= 0)
            throw new ArgumentNullException("secretKey");

        byte[] encrypted;

        // Create an AesCryptoServiceProvider object 
        // with the specified key and IV. 
        using (AesCryptoServiceProvider aesAlg = new AesCryptoServiceProvider())
        {
            aesAlg.Key = secretKey;
            aesAlg.IV = IV;

            // Create a decrytor to perform the stream transform.
            ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

            // Create the streams used for encryption. 
            using (MemoryStream msEncrypt = new MemoryStream())
            {
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        swEncrypt.Write(plainText);
                    }
                    encrypted = msEncrypt.ToArray();
                }
            }
        }
        return encrypted;
    }
    catch (System.Exception ex)
    {
        LogWriter.Instance.LogError(ClassName, "EncryptStringToBytes()", ex.Message + ";\tplainText=" + plainText + ";\t" + ex.StackTrace);
        return null;
    }
}

int main()
{
    byte[] encryptText = EncryptStringToBytes("some plain text", secretKey, iv);
    if (encryptText != null)
    {
        try
        {
            File.WriteAllBytes(filePath, encryptText);
        }
        catch (Exception ex)
        {
            LogWriter.Instance.LogError(ClassName, "SaveBuffToFile()", ex.Message + ";\tFilePath=" + path + ";\t" + ex.StackTrace);
        }
    }
}

在主函数中,我加密纯文本,并通过调用结果保存到文件File.WriteAllBytes(filePath, encryptText); 。 但有时内容文件中包含的所有空字符(“\ 0”)。 波纹图像文件的内容时,我HexaEditor打开

一个月这个错误发生约一次运行每天8小时的应用程序。

我认为,该文件可能已损坏。 但我认为,这种情况下不被损坏引起的,因为有一个文件夹中的10个配置文件,但只有7个文件,使用加密遇到这个错误,而通过纯文本(不使用加密)保存3个文件从未遇到此错误。

因此,我认为造成AesCryptoServiceProvider的问题。 任何人都请帮助我。

谢谢!

Answer 1:

:由于Damien_The_Unbeliever和他的测试,这个答案已经被发现是错误的 ,可能很快会被删除。 在此之前,它应该帮助他人避免走这条路。


您可能必须与比赛条件ToArray()您的呼叫MemoryStream

你的代码张贴调用的之外的方法using语句StreamWriter ,使对象就会将刷新可以使用到底层的缓冲区CryptoStream由点,但呼叫是使用语句 CryptoStream ,这意味着有不保证对象将已刷新任何缓冲到底层MemoryStream通过这一点。

这就解释了错误的间歇性:

在你得到想要的结果的情况下,它可能是对CryptoStream的缓冲区被自动刷新到MemoryStream调用之前ToArray()只是靠运气。

在你得到错误结果的情况下, ToArray()调用返回从数据MemoryStream在之前的内部缓冲区(这是最有可能被初始化为零) MemoryStream已收到的全部(或任何)从数据CryptoStream

如果这是正确的,你可以让缓冲区冲洗确定性,并通过调用每次保证正确的结果FlushFinalBlock()CryptoStream从其下面的访问数据之前对象MemoryStream

这一变化后,代码如下:

[...]

// Create the streams used for encryption. 
using ( MemoryStream msEncrypt = new MemoryStream() ) {

    using ( CryptoStream csEncrypt = new CryptoStream( msEncrypt, encryptor, CryptoStreamMode.Write ) ) {

        using ( StreamWriter swEncrypt = new StreamWriter( csEncrypt ) ) {

            swEncrypt.Write( plainText );

        }

        csEncrypt.FlushFinalBlock();
        encrypted = msEncrypt.ToArray();

    }

}

[...]

看到:

CryptoStream.HasFlushedFinalBlock

这StackOverflow的答案是切向有关您的问题: https://stackoverflow.com/a/19742806



文章来源: Encrypt AesCryptoServiceProvider return zero byte array?