我有一些密码,像这样(缩写)
Public Class Encryption
Public Sub DoEncryption()
[...]
Try
cryptstream.CopyTo(msVerifyOut)
Catch ex As System.Security.Cryptography.CryptographicException
Throw New System.Security.Cryptography.CryptographicException("Not a valid keyfile or password incorrect", ex)
End Try
[...]
End Sub
End Class
Public Class MainClass
Public Sub UseEncryption
[...]
Dim Encrypter As New Encryption
Try
Encrypter.DoEncryption()
Catch ex As System.Security.Cryptography.CryptographicException
MessageBox.Show("Encryption failed: " & vbCrLf & ex.Message)
End Try
[...]
End Sub
End Class因此,行cryptstream.CopyTo(msVerifyOut)可能会抛出一个被捕获的CryptographicException,并使用自定义消息重新抛出一个新的CryptographicException (不管原始异常是否为InnerException )。
我希望Messagebox会说:Encryption failed: Not a valid keyfile or password incorrect。但事实并非如此,上面写的是Encryption failed: Original exception message。
我试着重现这样的场景:
Private Function Test() As Object
Try
Dim tst1 = Test1()
Return tst1
Catch ex As CryptographicException
Throw New CryptographicException("From Test", ex)
End Try
End Function
Private Function Test1() As Object
Throw New CryptographicException("From Test1")
End Function
Private Sub PerformTest()
Try
Dim tst = Test()
Catch ex As CryptographicException
MessageBox.Show(ex.Message)
End Try
End Sub但是在这里,Messagebox输出了我所期望的:From Test
因此,cryptstream.CopyTo(msVerifyOut)抛出异常的方式肯定与验证版本有一些不同,但我不知道区别是什么。
作为参考,引发的异常是:Padding is invalid and cannot be removed。我不是在问为什么抛出异常,而是为什么不能用不同的消息正确地重新抛出异常。
发布于 2018-05-16 17:42:34
这是个有趣的问题。让我们看看到底发生了什么。
我有一些代码(它是C#,但我相信您会理解我的意思):
using (var mem = new MemoryStream(data))
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
using (var cryptoStream = new CryptoStream(mem, decryptor, CryptoStreamMode.Read))
using (var bin = new BinaryReader(cryptoStream))
{
try
{
return bin.ReadBytes(data.Length);
}
catch (CryptographicException ex)
{
throw new Exception("Invalid password", ex);
}
}当我输入错误的密码时,我看到的是CryptographicException而不是我自己的new Exception("Invalid password", ex)。
让我们看看调试窗口:
"System.Security.Cryptography.CryptographicException" in System.Private.CoreLib.dll
"System.Exception" in my.dll
"System.Security.Cryptography.CryptographicException" in System.Security.Cryptography.Algorithms.dll正如您所看到的,我的异常被正确抛出,但是在它之后,新的CryptographicException再次被抛出。因此,我们看到一个不正确的异常。
问题在于退出CryptoStream.Dispose()块后调用的using方法。它可能调用FlushFinalBlock()方法,该方法抛出第二个CryptographicException。更多报道来自https://github.com/dotnet/corefx/issues/7779。
所以,把尝试/捕捉移到外面,你就会得到你想要的东西:
try
{
using (var mem = new MemoryStream(data))
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
using (var cryptoStream = new CryptoStream(mem, decryptor, CryptoStreamMode.Read))
using (var bin = new BinaryReader(cryptoStream))
{
return bin.ReadBytes(data.Length);
}
}
catch (CryptographicException ex)
{
throw new Exception("Invalid password", ex);
}https://stackoverflow.com/questions/49348201
复制相似问题