使用AesCryptoServiceProvider加密某些文件配置时遇到错误。摘要代码如下
1. Team1 91 Pts
2. Team2 89 Pts
3. Team3 87 Pts
在main函数中,我通过调用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);
}
}
}
来加密纯文本并将结果保存到文件中。但有时内容文件包含所有空字符(&#39; \ 0&#39;)。当我用HexaEditor
每天运行8小时的应用程序每月发生一次此错误。
我认为该文件可能已损坏。但我认为这种情况不是由腐败引起的,因为文件夹中有10个配置文件,但只有7个使用Encryption的文件遇到此错误,而3个通过纯文本保存的文件(不使用加密)从未遇到这个错误。
所以我认为AesCryptoServiceProvider引起的问题。 有人请帮帮我。
谢谢!
答案 0 :(得分:1)
注意:感谢Damien_The_Unbeliever和他的测试,我们发现这个答案是错误,很快就会被删除。在那之前,它应该帮助其他人避免走这条路。
您ToArray()
上的MemoryStream
来电可能会遇到竞争条件。
您发布的代码调用using
StreamWriter
语句的 方法,因此该对象将刷新它可能使用的任何缓冲区CryptoStream
CryptoStream
1}}到那时为止,但调用里面使用MemoryStream
的using语句,这意味着无法保证 对象将刷新任何缓冲区到那时为基础的CryptoStream
。
这可以解释这个错误的间歇性:
在您获得所需结果的情况下,可能是MemoryStream
的缓冲区在调用ToArray()
之前自动刷新到ToArray()
,只是运气好
在您收到错误结果的情况下,MemoryStream
调用会在MemoryStream
的内部缓冲区(最有可能被初始化为零)之前将数据返回到{ {1}}已收到CryptoStream
。
如果这一切都正确,您可以通过在CryptoStream
对象上调用FlushFinalBlock()
之前使缓冲区刷新确定性并保证每次正确的结果,然后才能从其基础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