我想使用 SecureString 来保存数据库的连接字符串。但是,一旦我将 SqlConnection 对象的 ConnectionString 属性设置为安全字符串的值,它肯定会对任何其他能够读取我的应用程序内存的应用程序可见吗?
我做了以下假设:
a) 我无法在托管内存之外实例化 SqlConnection 对象
b) 托管内存中的任何字符串都可以被Hawkeye等应用程序读取
我想使用 SecureString 来保存数据库的连接字符串。但是,一旦我将 SqlConnection 对象的 ConnectionString 属性设置为安全字符串的值,它肯定会对任何其他能够读取我的应用程序内存的应用程序可见吗?
我做了以下假设:
a) 我无法在托管内存之外实例化 SqlConnection 对象
b) 托管内存中的任何字符串都可以被Hawkeye等应用程序读取
当您需要将字符串传递给托管 API(例如设置 ConnectionString)时,您绝对正确,SecureString 不会为您提供任何好处。
它真的是为与安全的非托管 API 进行安全通信而设计的。
微软理论上可以考虑增强 SqlConnection 对象以支持安全的 ConnectionString,但我认为他们不太可能这样做,因为:
SecureString 实际上只在客户端应用程序中有用,例如,密码是从用户输入逐个字符构建的,而无需在托管字符串中包含整个密码。
在这样的环境中,更常见的是使用 Windows 身份验证来连接 SQL Server。
在服务器上,还有其他方法可以保护 SQL Server 凭据,首先是将服务器的访问权限限制为授权管理员。
2012
Microsoft确实通过将SqlCredential传递给新的 SqlConnection.Credential属性来增强SqlConection对象以支持安全的ConnectionString :
SecureString pwd = AzureVault.GetSecretStringSecure("ProcessPassword");
SqlCredential = new SqlCredential("Richard", pwd)
connection.Credential = cred;
不幸的是,没有其他DbConnection后代 (例如,OdbcConnection、OleDbConnection、OracleConnection、EntityConnection、DB2Connection)支持它。
是的,你可以,是的,你应该使用 SecureString 来避免让密码在内存中保持清晰并受到攻击。您需要使用密码属性是 SecureString 的新 SqlCredential 类,而不是使用 sql 连接字符串。请参阅以下文章以获取帮助。
https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcredential.password(v=vs.110).aspx
http://www.codeproject.com/Tips/408901/Storing-your-connection-string-password-in-SecureS
为什么连接字符串有问题?密码不是您想要保护的(除非您将密码放在连接字符串中,这对于我见过的所有驱动程序都是可选的)。话虽如此,密码通常必须在某个时候在内存中“明文”(除非驱动程序有一些允许加密密码或其他东西的api,但无论如何这实际上可能没有多大帮助)。
通常这不是问题,因为进程处于安全环境中,例如在 Web 服务器上,或者作为系统管理员类型的帐户运行(因此普通用户无法访问进程内存),或者通常两者兼而有之。如果这是在用户空间中运行的客户端机器上,您必须假设该过程无论如何都会受到损害,这将无济于事。一旦你确保了这个过程,你就不必担心这样的事情。
将 SecureString 值分配给 SQLConnection.ConnectionString 将绕过安全性,使其无用。
SecureString 旨在解决这些正常的字符串问题,参考:
恕我直言,SecureString 类型是一个伪劣安全实现的补丁,目前 SecureString 还没有在整个框架中实现,所以它的好处不能被充分利用。
我有同样的问题,我选择 RSA 加密将敏感信息存储在内存中。
另一种解决方案是通过数据库服务器上的服务托管您的数据访问层,该服务在本地系统帐户下运行,该帐户连接到数据库并提供数据,而本地用户将无权访问服务配置。
如果您担心安全性,我建议您应该在 SQL Server 中启用 SSL 并使用 SSL 与其通信。