ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

c# – 使用加密后,在终结器线程中获取“ReleaseHandleFailed”MDA

2019-06-14 04:55:42  阅读:185  来源: 互联网

标签:c cryptography


我在循环中第二次运行此代码后获得了MDA(使用不同的文件参数:

byte[] encryptedData = File.ReadAllBytes(file); // before this line it throws, see exception below
long dataOffset;

using (var stream = new MemoryStream(encryptedData))
using (var reader = new BinaryReader(stream))
{
    // ... read header information which is not encrypted
}


using (var stream = new MemoryStream(encryptedData))
{
    stream.Seek(dataOffset, SeekOrigin.Begin);

    using (var aesAlg = new AesCryptoServiceProvider())
    using (var decryptor = aesAlg.CreateDecryptor(key, iv))
    using (var csDecrypt = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
    using (var reader = new BinaryReader(csDecrypt))
    {
        decrypted = reader.ReadBytes((int)(encryptedData.Length - dataOffset));
    }
}

MDA如下:

A SafeHandle or CriticalHandle of type ‘Microsoft.Win32.SafeHandles.SafeCapiKeyHandle’ failed to properly release the handle with value 0x000000001BEA9B50. This usually indicates that the handle was released incorrectly via another means (such as extracting the handle using DangerousGetHandle and closing it directly or building another SafeHandle around it.)

堆栈跟踪没有太多信息:

mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Dispose(bool disposing) + 0x10 bytes
mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Finalize() + 0x1a bytes

我怀疑其中一个流或CryptoServiceProvider由于某种原因未发布.除此之外,代码运行良好,并做到了预期. MDA在控件到达方法的第一行之前发生.

我怎么能正确地做到这一点?问题的根本原因是什么?

解决方法:

很明显,终结器线程正在最终确定已经处理好的SafeHandle.这是AesCryptoServiceProvider.Dispose(bool)方法的实现:

protected override void Dispose(bool disposing)
{
    try {
        if (disposing) {
            if (this.m_key != null) this.m_key.Dispose();
            if (this.m_cspHandle != null) this.m_cspHandle.Dispose();
        }
    }
    finally {
        base.Dispose(disposing);
    }
}

三个错误:

>处理后,它不会将m_key字段设置为null
> GC.SuppressFinalize()不会被调用,甚至不会被.NET 3.5中的基类调用
> SafeCapiKeyHandle类不会使其ReleaseHandle()方法中存储的句柄无效.

所有三个错误的组合足以触发此MDA.它仍然在.NET 4.0中被窃听,但至少GC.SuppressFinalize由SymmetricAlgorithm.Dispose(bool)调用,因此不会使用终结器.

鼓励看到框架大师搞砸了.您可以在connect.microsoft.com上报告问题.要阻止调试器唠叨这一点,请使用Debug Exceptions,Managed Debugging Assistants,取消ReleaseHandleFailed.默认情况下,这个是未被攻击的,这肯定是你第一个注意到这个bug的原因.

我认为第三个错误使这成为一个关键问题顺便说一句,从技术上讲,这个错误可能会导致循环句柄值被关闭.虽然赔率非常小.相当讽刺的是,鉴于这是一个安全的句柄类.

标签:c,cryptography
来源: https://codeday.me/bug/20190614/1237243.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有