我编写了一个过程,其中文件被加密并上传到 Azure,然后必须解密下载过程,这会失败并出现“填充无效且无法删除”错误,或“要解密的数据长度为无效的。”错误。
我在网上尝试了很多解决方案,包括C# 使用 RijndaelManaged 和 CryptoStream 解密 mp3 文件 https://stackoverflow.com/questions/28692444/c-sharp-decrypting-mp3-file-using-rijndaelmanaged-and-cryptostream,但它们似乎都不起作用,我最终只是在这两个错误之间来回跳动。加密过程使用与解密相同的密钥/IV 对,并且由于它将解密流的一部分,我觉得工作正常 - 它最终会因上述错误而死亡。
这是我的代码,有什么想法吗?请注意,这三个变体(cryptoStream.CopyTo(decryptedStream)
, do {}
and while
)不是一起运行的 - 它们在这里显示我已经尝试过的选项,所有这些都失败了。
byte[] encryptedBytes = null;
using (var encryptedStream = new MemoryStream())
{
//download from Azure
cloudBlockBlob.DownloadToStream(encryptedStream);
//reset positioning for reading it back out
encryptedStream.Position = 0;
encryptedBytes = encryptedStream.ConvertToByteArray();
}
//used for the blob stream from Azure
using (var encryptedStream = new MemoryStream(encryptedBytes))
{
//stream where decrypted contents will be stored
using (var decryptedStream = new MemoryStream())
{
using (var aes = new RijndaelManaged { KeySize = 256, Key = blobKey.Key, IV = blobKey.IV })
{
using (var decryptor = aes.CreateDecryptor())
{
//decrypt stream and write it to parent stream
using (var cryptoStream = new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read))
{
//fails here with "Length of the data to decrypt is invalid." error
cryptoStream.CopyTo(decryptedStream);
int data;
//fails here with "Length of the data to decrypt is invalid." error after it loops a number of times,
//implying it is in fact decrypting part of it, just not everything
do
{
data = cryptoStream.ReadByte();
decryptedStream.WriteByte((byte)cryptoStream.ReadByte());
} while (!cryptoStream.HasFlushedFinalBlock);
//fails here with "Length of the data to decrypt is invalid." error after it loops a number of times,
//implying it is in fact decrypting part of it, just not everything
while ((data = cryptoStream.ReadByte()) != -1)
{
decryptedStream.WriteByte((byte)data);
}
}
}
}
//reset position in prep for reading
decryptedStream.Position = 0;
return decryptedStream.ConvertToByteArray();
}
}
其中一条评论提到想知道什么ConvertToByteArray
是的,这只是一个简单的扩展方法:
/// <summary>
/// Converts a Stream into a byte array.
/// </summary>
/// <param name="stream">The stream to convert.</param>
/// <returns>A byte[] array representing the current stream.</returns>
public static byte[] ConvertToByteArray(this Stream stream)
{
byte[] buffer = new byte[16 * 1024];
using (MemoryStream ms = new MemoryStream())
{
int read;
while ((read = stream.Read(buffer, 0, buffer.Length)) > 0)
{
ms.Write(buffer, 0, read);
}
return ms.ToArray();
}
}
但代码永远不会达到这一点——在我达到这一点之前它就死了。