首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >.NET安全内存结构

.NET安全内存结构
EN

Stack Overflow用户
提问于 2009-07-22 17:37:20
回答 6查看 9.9K关注 0票数 9

我知道.NET库提供了一种以受保护/安全的方式存储字符串= SecureString的方法。

我的问题是,如果我想存储一个字节数组,那么保存它的最好、最安全的容器是什么?

EN

回答 6

Stack Overflow用户

发布于 2013-07-08 08:53:05

了解System.String类型的漏洞非常重要。要使它完全安全是不可能的,SecureString的存在是为了将暴露的风险降到最低。System.String有风险,因为:

  • 它们的内容在其他地方可见,而不必使用调试器。攻击者可以查看分页文件( RAM
  • System.String ),它保留了被交换到磁盘的内存页面的内容,以便为需要c:\pagefile.sys的其他程序腾出空间。

是不可变的,你不能在使用后擦除字符串的内容

  • 垃圾收集堆压缩堆,但不重置被释放的内存的内容。这可能会在内存中留下字符串数据的副本,而您的程序完全无法访问该副本。

这里的明显风险是,字符串内容在字符串使用很长时间后才可见,因此极大地增加了攻击者看到它的可能性。SecureString通过将字符串存储在非托管内存中提供了一种解决方法,在非托管内存中,它不会受到垃圾回收器的影响,不会留下字符串内容的零散副本。

现在应该很清楚了,如何创建自己的安全阵列版本,并提供与SecureString相同的保证。你没有不可变性的问题,在你使用数组之后清理它不是问题。这本身几乎总是足够好的,隐含在减少暴露的可能性是,您也不会保持对数组的引用很长时间。因此,在垃圾收集之后,阵列数据的未清理副本存活的几率应该已经很低了。您也可以降低这种风险,仅适用于小于85,000字节的数组。要么像SecureString那样做,要么使用Marshal.AllocHGlobal()。或者通过固定数组GCHandle.Alloc()更容易。

票数 11
EN

Stack Overflow用户

发布于 2013-07-08 03:08:45

从.Net 2.0开始使用ProtectedData.Protect方法,似乎将作用域设置为DataProtectionScope.CurrentUser应该会产生与安全字符串相同的预期效果

示例用法取自此处

http://msdn.microsoft.com/en-us/library/system.security.cryptography.protecteddata.protect.aspx

代码语言:javascript
复制
using System;
using System.Security.Cryptography;

public class DataProtectionSample
{
// Create byte array for additional entropy when using Protect method. 
    static byte [] s_aditionalEntropy = { 9, 8, 7, 6, 5 };

    public static void Main()
    {
// Create a simple byte array containing data to be encrypted. 

byte [] secret = { 0, 1, 2, 3, 4, 1, 2, 3, 4 };

//Encrypt the data. 
        byte [] encryptedSecret = Protect( secret );
        Console.WriteLine("The encrypted byte array is:");
        PrintValues(encryptedSecret);

// Decrypt the data and store in a byte array. 
        byte [] originalData = Unprotect( encryptedSecret );
        Console.WriteLine("{0}The original data is:", Environment.NewLine);
        PrintValues(originalData);

    }

    public static byte [] Protect( byte [] data )
    {
        try
        {
            // Encrypt the data using DataProtectionScope.CurrentUser. The result can be decrypted 
            //  only by the same current user. 
            return ProtectedData.Protect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );
        } 
        catch (CryptographicException e)
        {
            Console.WriteLine("Data was not encrypted. An error occurred.");
            Console.WriteLine(e.ToString());
            return null;
        }
    }

    public static byte [] Unprotect( byte [] data )
    {
        try
        {
            //Decrypt the data using DataProtectionScope.CurrentUser. 
            return ProtectedData.Unprotect( data, s_aditionalEntropy, DataProtectionScope.CurrentUser );
        } 
        catch (CryptographicException e)
        {
            Console.WriteLine("Data was not decrypted. An error occurred.");
            Console.WriteLine(e.ToString());
            return null;
        }
    }

    public static void PrintValues( Byte[] myArr )  
    {
          foreach ( Byte i in myArr )  
            {
                 Console.Write( "\t{0}", i );
             }
      Console.WriteLine();
     }

}
票数 3
EN

Stack Overflow用户

发布于 2009-07-22 17:48:01

要做到这一点,没有“最佳”方法--您需要确定您试图防范的威胁,以便决定要做什么,或者是否确实需要做些什么。

需要注意的一点是,与不可变的字符串不同,您可以在处理完字节数组中的字节后将它们清零,这样就不会出现SecureString设计用来解决的问题。

加密数据可能适用于某些问题,但随后您将需要确定如何保护密钥,使其免受未经授权的访问。

我发现很难想象以这种方式加密字节数组会有什么用处。更多关于你想要做什么的细节将会有所帮助。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1166952

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档