使用SecureString建立SQL连接

9
我想使用SecureString来保存数据库连接字符串。但是,一旦我将SqlConnection对象的ConnectionString属性设置为SecureString的值,它肯定会对任何能够读取我的应用程序内存的其他应用程序可见。
我做了以下假设:
a)我无法在托管内存之外实例化SqlConnection对象
b)托管内存中的任何字符串都可以被诸如Hawkeye这样的应用程序读取

2
显然,Hawkeye 1.2.0可以显示SecureStrings...那么,你的问题是什么? - DK.
1
哦,那么安全字符串有什么意义呢? - Rich
连接字符串的 Persist Security Info 属性可能会引起您的兴趣。 - Sql Surfer
5个回答

5

你说得完全正确,SecureString在需要将字符串传递给托管API(例如设置ConnectionString)时并没有任何好处。

它真正设计用于与安全的非托管API进行安全通信。

微软理论上可以考虑增强SqlConnection对象以支持安全的ConnectionString,但我认为他们不太可能这样做,因为:

  • SecureString在客户端应用程序中才真正有用,例如从用户输入逐个字符构建密码而不会将整个密码存储在托管字符串中。

  • 在这种环境下,更常见的是使用Windows身份验证连接到SQL Server。

  • 在服务器上,保护SQL Server凭据的其他方法包括限制对服务器的访问权限仅授予授权管理员。


2012

微软加强了 SqlConection 对象的功能,通过将 SqlCredential 传递给新的 SqlConnection.Credential 属性来支持安全的 ConnectionString

SecureString pwd = AzureVault.GetSecretStringSecure("ProcessPassword");
SqlCredential = new SqlCredential("Richard", pwd)
connection.Credential = cred;

很遗憾,没有其他DbConnection的后代支持它 (例如,OdbcConnection、OleDbConnection、OracleConnection、EntityConnection、DB2Connection)


4
在使用SQL Server身份验证时,.NET 4.5将允许将密码作为SecureString传递:ADO.NET 4.5中的新功能 - Lee Grissom
我认为SecureString适用于所有类型的秘密通信,以安全方式进行,而不限于非托管API。根据Lee的说法,SecureString受.NET 4.5支持。我个人正在企业支持工程环境中工作,在这种环境中,最低级别的支持人员可能可以访问SQL中的某些数据,但未被授予了解SQL用户密码的知识。相反,该密码是使用证书加密的,程序被授予使用该证书,但不允许用户使用。 - David Burg
@DavidBurg - 我不理解你的观点。在.NET 4.5中,SqlConnection.ConnectionString仍然不使用SecureString。如果可以避免需要密码,那么显然这是更好的解决方案,但并非总是如此。而使用证书进行身份验证的程序不需要SecureString。 - Joe
@Joe - 关键是您不再需要包含用户凭据和密码的SqlConnection.ConnectionString,而是使用SqlCredential对象传递凭据,其中密码被用作SecureString。是的,证书是另一种完全不同的方法。 SqlCredential是一个更小的足迹变化,因为您可以继续使用密码。 - David Burg

5

0

将SecureString值分配给SQLConnection.ConnectionString将绕过安全性,使其无用。

SecureString旨在解决这些普通字符串问题,ref

  • 未固定,垃圾收集器可以将其移动,留下内存中的副本
  • 未加密
  • 如果您的进程被交换到磁盘上,字符串将停留在交换文件中
  • 不可变,修改它将保留旧版本和新版本在内存中
  • 使用完后没有清除方法

在我看来,SecureString类型是一个修补程序,用于修复不良的安全实现,目前SecureString尚未在整个框架中实现,因此无法充分利用其优势。

我有同样的问题,我选择RSA加密将敏感信息存储在内存中。

另一种解决方案是通过数据库服务器上的服务托管数据访问层,该服务在本地系统帐户下运行,连接到数据库并提供数据,而本地用户将无法访问服务配置。


随着.NET的新版本,SecureString实现更加全面,使得原始响应有些过时。 - David Burg

0
为什么连接字符串是个问题?难道不应该保护密码(除非你将密码放在连接字符串中,但我见过的所有驱动程序都是可选的)。话虽如此,密码通常必须在某个时刻“明文”存储在内存中(除非驱动程序具有允许加密密码的api,但这可能并没有太大帮助)。
通常情况下,这不是问题,因为进程处于安全环境中,例如在Web服务器上或作为系统管理员类型的帐户运行(因此普通用户无法访问进程内存),或通常两者都有。如果这是在客户端机器上以用户身份运行,那么您必须假设进程已经被攻击了,这并没有帮助。一旦您保护了进程,就不必担心这样的事情了。

最终用户不是唯一的威胁。第三方 API 也可能成为其中之一。尽管我同意,如果您正在编写一个应用程序并且了解/信任其每个依赖项,那么这可能并不是什么大问题。但在某些公司中,您并没有这种奢侈条件。 - Crono

-3
如果您非常关注安全问题,我建议您在SQL服务器中启用SSL,并使用SSL与其通信。

2
连接密码在某个时刻仍需存储于内存中,不是吗? - user159335
@JonB @Shamika,是的,我认为这也是。 - Rich
我不明白使用SSL与问题有什么关系。 - Joe
这与原始问题有些不相关。 - David Burg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接