【问题标题】:Use SecureString for credit card numbers将 SecureString 用于信用卡号
【发布时间】:2011-03-19 18:39:03
【问题描述】:

我一直在研究使用 System.Security.SecureString 类在处理信用卡号时将它们保存在内存中。有没有人使用 SecureString 类来保存信用卡号,或者大多数人只使用普通的 System.String 类?

【问题讨论】:

  • 更好的问题:System.SecureString 对于这个应用程序来说真的足够安全吗?
  • @JSBangs:嗯,据我了解,System.SecureString 专门用于此目的。但是,由于 .NET 框架中的许多其他 API 仍然使用普通的 System.String 类,因此很难在整个应用程序中维护字符串的安全性。我想我的问题确实是:尝试在内存中端到端保护数据是否值得努力,或者 API 中是否存在太多不支持的漏洞,以至于无论如何都无法实现真正​​的安全性?

标签: .net credit-card securestring


【解决方案1】:

如果要在内存中缓存很长时间,我会将 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);
        }
    }

【讨论】:

  • 这违背了目的。一旦从 System.String 转换为 System.String,它就不再安全了。
  • @Hans -- 我相信我在回复的第二段中解决了这个缺点。
【解决方案2】:

PCI-DSS 的角度来看,不需要保护仅存储在内存中的卡号。

PCI 仅声明卡号保留在磁盘上,或通过网络传输必须加密。这是解决问题的常识性方法。使用 SecureString 将确保字符串永远不会缓存到磁盘,但正如您所说 - 它使用起来很麻烦。不过这篇文章有一些很好的建议:https://stackoverflow.com/questions/122784/hidden-net-base-class-library-classes#123141

从理论上讲,保护内存听起来会增加力量,但实际上,如果坏人可以访问 RAM,那么无论如何,它的游戏就结束了。

【讨论】:

  • PCI 要求是在这里寻找答案的正确位置^^
【解决方案3】:

2010 年之前接受的答案在当时可能是正确的,但请注意PCI DSS 3.0 第 6.5 节,其中指出:

对开发人员进行安全编码技术培训,包括如何避免 常见的编码漏洞,以及了解数据的敏感程度 在内存中处理。

最终要遵守行业最佳实践。

鉴于近年来备受瞩目的泄露事件,其中敏感数据(包括信用卡信息)被恶意软件、攻击者等抓取内存,因此更加关注保护敏感信息的安全,即使是在内存中也是如此。

尽可能使用 SecureString。

在不可能的情况下,只需了解您面临的挑战。由于字符串是不可变的,并且不能总是依赖垃圾收集,因此您只需要使用您所拥有的即可。我读过的一种方法是将字符串变成 BSTR,将其复制到固定字符串中,然后在使用后将 BSTR 和固定字符串都归零。感觉有点“hacky”,但总比什么都不做要好。

如果纯粹在 winform 应用程序中进行信用卡号捕获,则将卡号安全地保存在内存中是完全可行的。

不过,对于 ASP.NET Web 应用程序,我不确定...我没有尝试过,但 SO 上的 general consensus 似乎不值得。此外,MSDN 特别提到了 ASP.NET 应用程序,他说:

在 ASP.NET 中不太适合使用 SecureString 类 应用程序。您不太可能从网页中提取数据 包含敏感数据(如信用卡号)和地点 它在 SecureString 内,但尚未通过 中间系统。字符串对象

您的项目可能已经完成,但希望这会对其他人有所帮助。

【讨论】:

    【解决方案4】:

    不要使用安全字符串。 PG 正在弃用它。观看视频,他们概述了无数的安全问题。 https://github.com/dotnet/apireviews/tree/master/2015-07-14-securestring.

    【讨论】:

      猜你喜欢
      • 2014-08-14
      • 1970-01-01
      • 2014-02-27
      • 2012-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-18
      相关资源
      最近更新 更多