sha*_*oth 36 .net c# security encryption securestring
根据MSDN SecureString内容被加密以增加安全性,因此如果程序被交换到磁盘,则不能嗅探字符串内容.
我想知道这样的加密怎么样?算法是固定的,因此要么是熟知的,要么是免赔额的(比如工业算法中广泛使用的七种算法之一),并且程序中必须有一个密钥.因此,攻击者可以获取加密的字符串,获取密钥并解密数据.
这种加密如何有用?
Net*_*rel 18
我引用了一篇关于用于推导密钥的DPAPI的文章.这应该回答您关于SecureString的大多数问题.
是的,SecureString有缺点并且不完全安全,有方法可以访问数据,例如,在MSDN上提到将Hawkeye注入进程是一种提取SecureString的方法.我没有亲自核实这个断言.
DAPI是一种基于对称的加密技术,这意味着它使用相同的密钥来加密和解密数据.在了解如何使用DAPI的一些示例之前,值得介绍DAPI如何管理其密钥.在大多数情况下,DAPI密钥管理过程是隐形的,您通常不需要担心它,这是DAPI是一个好方法的主要原因.
在介绍中我写道,主密钥是从用户的登录密码生成的.这不是完整的图片.实际发生的是Windows使用用户的登录密码生成主密钥.此主密钥使用用户密码进行保护,然后与用户的配置文件一起存储.然后,该主密钥用于导出许多其他密钥,而这些密钥则用于保护数据.
Windows之所以这样做,是因为它允许应用程序在生成单个密钥的过程中添加称为熵的附加信息.您会看到在用户的登录帐户下运行的每个应用程序是否使用相同的密钥,然后每个应用程序都可以取消保护受DAPI保护的数据.有时您可能希望应用程序能够共享受DAPI保护的数据; 但是,有时你不会.通过让应用程序为密钥的生成贡献熵,该密钥变为特定于应用程序,并且如果它们知道熵,则该应用程序保护的任何数据都只能再次受到保护.
虽然生成主密钥,然后使用该主密钥生成其他密钥来进行实际加密,但看起来似乎是一个冗长的方法,它确实有一个主要优势.由于在用户密码保护的主密钥和用于保护数据的实际密钥之间存在额外的抽象级别,这意味着当用户更改其密码时,只需要重新保护主密钥; 没有受保护的数据需要重新保护.由于主密钥的大小比数据小得多,因此可以显着节省性能.
当用户的密码改变时,当然会生成新的主密钥.然后,这个新的主密钥用于生成新的单个密钥.但是,由于所有先前生成的单个密钥都是从旧主密钥派生的,因此Windows需要存储所有以前的主密钥.Windows永远不会忘记主密钥,所有受保护的数据都标有GUID,指示使用哪个主密钥来保护数据.因此,在适应性方面,DAPI能够应对用户密码的更改,同时确保a)受保护的数据不需要重新保护,以及b)用于先前保护数据的密钥仍然可用,以及c )它会自动为您完成所有这些.
除非计算机是域的成员,否则DAPI只能在用于保护它的同一台计算机上进行不受保护的数据.
除了允许用户级保护之外,主密钥基于用户密码,并且一个用户的受保护数据不能被另一个用户保护,DAPI还提供机器级保护,因为主密钥基于机器特定信息.机器级主密钥允许应用程序存储受保护的数据,以便应用程序的所有用户不受其保护.已经描述的过程的唯一区别是主密钥是根据机器特定信息而不是用户特定信息生成的.
Dan*_*ite 11
我在代码中查看了一点,它使用Windows advapi32来完成它的脏工作.因此密钥不存储在应用程序的内存中.
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static int SystemFunction040([In, Out] SafeBSTRHandle pDataIn, [In] uint cbDataIn, [In] uint dwFlag)
Run Code Online (Sandbox Code Playgroud)
哪个更为人所知RtlEncryptMemory.
它用RtlDecryptMemory(SystemFunction041)解密.
我确信编译器也能做到这一点SecurityCriticalAttribute.
使用4.0反映编辑此内容.其他版本可能不同.
正如其他人已经回答的那样,内容SecureString是使用DPAPI加密的,因此密钥不会存储在您的应用程序中,它们是操作系统的一部分.我不是100%肯定,但我认为SecureString使用特定于用户的密钥,因此即使另一个进程获得对内存块的访问,它也必须在相同的凭据下运行才能简单地解密使用DPAPI的内容.即使没有,机器密钥(理论上)也可以防止字符串在转移到另一个系统时被轻易解密.
更重要的SecureString是如何以及何时使用它.它应该用于存储需要在"延长"时间段内保留在内存中的字符串数据,但这些数据在解密形式中并不常用.在某些时候,你将不得不将它解密为常规的旧的System.String,或者System.Char[].这是它在内存中最容易受到攻击的时候.如果你经常这样做,那么你有多个解密字符串的副本在内存中漂浮等待收集.
作为一般规则,如果我正在读取我需要保留以便不经常使用的加密数据(例如登录凭证)(例如,PayPal或Amazon API交互),那么我将这些凭证存储/缓存为SecureString,然后将其解密为 -只需要足够长的时间来进行Web服务调用,并确保任何解密副本的生命周期只有几行代码.
使用关键块或类似提示CLR,使用解密字符串时不应进行上下文切换,以提高在缓存或交换内存之前收集任何解密副本的可能性.
| 归档时间: |
|
| 查看次数: |
9904 次 |
| 最近记录: |