我一直在研究使用 System.Security.SecureString 类在处理信用卡号时将它们保存在内存中。有没有人使用 SecureString 类来保存信用卡号,或者大多数人只使用普通的 System.String 类?
4 回答
从PCI-DSS 的角度来看,不需要保护仅存储在内存中的卡号。
PCI 仅声明卡号保留在磁盘上,或通过网络传输必须加密。这是解决问题的常识性方法。使用 SecureString 将确保字符串永远不会缓存到磁盘,但正如您所说 - 它使用起来很麻烦。不过这篇文章有一些很好的建议:https ://stackoverflow.com/questions/122784/hidden-net-base-class-library-classes#123141
从理论上讲,保护内存听起来会增加力量,但实际上,如果坏人可以访问 RAM,那么无论如何它几乎都游戏结束了。
2010 年之前接受的答案在当时可能是正确的,但请注意PCI DSS 3.0第 6.5 节,其中指出:
培训开发人员使用安全编码技术,包括如何避免常见的编码漏洞,以及了解如何在内存中处理敏感数据。
归根结底是要遵守行业最佳实践。
鉴于近年来备受瞩目的数据泄露事件,其中敏感数据(包括信用卡信息)被恶意软件、攻击者等抓取内存,因此更加关注保护敏感信息的安全,即使是在内存中也是如此。
尽可能使用 SecureString。
在不可能的情况下,只需了解您面临的挑战。由于字符串是不可变的,并且不能总是依赖垃圾收集,因此您只需要使用您所拥有的即可。我读过的一种方法是将字符串变成 BSTR,将其复制到固定字符串中,然后在使用后将 BSTR 和固定字符串都归零。感觉有点“hacky”,但总比什么都不做要好。
如果纯粹在 winform 应用程序中进行信用卡号捕获,则将卡号安全地保存在内存中是非常可行的。
但是,对于 ASP.NET Web 应用程序,我不确定……我还没有尝试过,但是关于 SO 的普遍共识似乎不值得。此外,MSDN专门提到了 ASP.NET 应用程序,说:
在 ASP.NET 应用程序中使用 SecureString 类不太合适。您不太可能从包含敏感数据(例如信用卡号)的网页中提取数据并将其放在 SecureString 中而无需通过中间系统。字符串对象
您可能已经完成了您的项目,但希望这会对其他人有所帮助。
如果要长时间缓存在内存中,我将 SecureString 用于其他东西(不是信用卡)。
我一直遇到的问题是,您仍然必须将其编组为普通字符串才能实际将其用于任何事情,因此它的实用性确实受到限制。
我创建了几个扩展方法来简化它们的工作:
public static unsafe SecureString Secure(this string source)
{
if (source == null)
return null;
if (source.Length == 0)
return new SecureString();
fixed (char* pChars = source.ToCharArray())
{
SecureString secured = new SecureString(pChars, source.Length);
return secured;
}
}
public static string Unsecure(this SecureString source)
{
if (source == null)
return null;
IntPtr bstr = Marshal.SecureStringToBSTR(source);
try
{
return Marshal.PtrToStringUni(bstr);
}
finally
{
Marshal.ZeroFreeBSTR(bstr);
}
}
不要使用安全字符串。PG 正在弃用它。观看视频,他们概述了无数的安全问题。 https://github.com/dotnet/apireviews/tree/master/2015-07-14-securestring。