我们有一个使用Entity Framework在C#MVC应用程序中加密的数据库字段。该部分适用于加密和解密。我们需要在SSRS报告中显示解密的数据。
我采用了Decrypt方法并将其转换为VB.Net并放在报告后面的代码中。调用StreamReader
ReadToEnd
方法时出错。我们在网上找到了一些关于尝试关闭已经关闭的流的问题。此流仅从一次读取,我们正在读取整个流,因此不应该在此时关闭。
我尝试从cryptoStream中读取Length - 1
字节并且没有抛出错误。如果我尝试读取Length
个字节,我会得到同样的错误。如果我读取除了一个字节之外的所有字节然后只读取最后一个字节,则会得到相同的错误。堆栈跟踪和代码如下。任何帮助将不胜感激。
堆栈跟踪:
at System.Security.Cryptography.RijndaelManagedTransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
at System.Security.Cryptography.CryptoStream.FlushFinalBlock()
at System.Security.Cryptography.CryptoStream.Dispose(Boolean disposing)
at System.IO.Stream.Close()
at System.IO.Stream.Dispose()
at ReportExprHostImpl.CustomCodeProxy.Decrypt(String ciphertext)
代码:
public function Decrypt(byval ciphertext as string) as string
dim message as string
dim key as string
dim saltSize as integer
saltsize = 32
key = "KEYGOESHERE"
dim allTheBytes as byte()
allTheBytes = Convert.FromBase64String(ciphertext)
dim saltBytes as byte()
saltBytes = new byte(saltsize) {}
dim ciphertextBytes as byte()
ciphertextBytes = new byte(allTheBytes.Length - saltSize) {}
dim i as integer
for i = 0 to saltsize - 1
saltBytes(i) = allTheBytes(i)
next i
for i = saltSize to (allTheBytes.Length - 1)
ciphertextBytes(i - saltSize) = allTheBytes(i)
next i
try
using keyDerivationFunction as System.Security.Cryptography.Rfc2898DeriveBytes = new System.Security.Cryptography.Rfc2898DeriveBytes(key, saltBytes)
dim keyBytes as byte()
keyBytes = keyDerivationFunction.GetBytes(32)
dim ivBytes as byte()
ivBytes = keyDerivationFunction.GetBytes(16)
using aesManaged as System.Security.Cryptography.AesManaged = new System.Security.Cryptography.AesManaged()
aesManaged.Padding = System.Security.Cryptography.PaddingMode.PKCS7
aesManaged.Mode = System.Security.Cryptography.CipherMode.CBC
using decryptor as System.Security.Cryptography.ICryptoTransform = aesManaged.CreateDecryptor(keyBytes, ivBytes)
using memoryStream as System.IO.MemoryStream = new System.IO.MemoryStream(ciphertextBytes)
using cryptoStream as System.Security.Cryptography.CryptoStream = new System.Security.Cryptography.CryptoStream(memoryStream, decryptor, System.Security.Cryptography.CryptoStreamMode.Read)
using streamReader as System.IO.StreamReader = new System.IO.StreamReader(cryptoStream)
message = streamReader.ReadToEnd()
return message
end using
end using
end using
end using
end using
end using
catch e as Exception
return e.StackTrace
end try
end function
答案 0 :(得分:1)
这听起来像填充错误。首先,CBC模式下的AES需要精确的消息大小才能解密,是块大小的N倍(16字节)。如果消息具有此大小,则AES CBC密文将始终解密。任何其他问题都只能与填充有关。所以会发生的是,最后解密的纯文本没有正确的填充,并且会发生异常。
现在来了有趣的部分;在以下情况下会发生此错误:
换句话说,如果出现问题,可能在删除填充字节期间会出现错误。如果运气不好,最后一个不正确的块仍以字节值01
十六进制结束,并且填充成功,表明填充不替代完整性保护。