如何保存SQL服务器密码

How to save SQL server password

我们有一个应用程序 运行 多个服务和可执行文件。其中一些需要访问 SQL 数据库,因此我需要将 SQL 服务器密码存储在某处。为了避免直接访问密码,密码被加密存储。要解密字符串,可以调用加密 DLL,返回明文密码。困扰我的是,如何避免任何人都可以解密密码。以下选项已被讨论并被丢弃,因为它们或多或少没有解决直接访问明文密码的问题:

  1. crypto dll 包含解密密码所需的所有信息:任何恶意用户都可以调用 DLL 来使用自己的组件解密密码

  2. 使用DPAPI,我需要将范围设置为LocalMachine,这意味着任何登录到本地系统的用户都可以解密密码。

2a。使用 DPAPI 和服务组件 运行 特殊帐户可以解决 "any local user can use the Unprotect method of DPAPI to decrypt the password" 问题,但是,恶意用户仍然可以使用自己的组件调用加密服务。

  1. 加密 DLL 请求密码,并且 encrypts/decrypts 使用 RijndaelManaged 实例。每个调用 DLL 都必须知道密码,这意味着我只是将问题转移到另一个组件。

  2. 集成安全不是一个选项,客户的安全策略拒绝使用 IS

任何指示如何解决这个问题?

这将取决于您认为系统中的用户将走多远才能获得连接字符串。

  • 他们是否需要域访问权限才能使用您的应用程序?
  • 你能限制进入你的 SQL 服务器的 IP 地址吗?
  • 用户在他们的机器上有管理员权限吗?
  • e.t.c.

像上面这样的事情会缩小可以获得访问权限的潜在用户的范围。 其他一些似乎很突出的事情是:

  • 将 KEY 和 IV 移到 DLL 之外,因为如果它被盗,这似乎是单点故障
  • 混淆应用程序代码中的密钥和 iv 或存储在证书中,可能使用 DPAPI
  • 锁定对程序文件的访问,使应用程序 运行 处于受限用户之下。

这里有一些其他提示:

handling key and iv values
storing key in certicates
restrict SQL access by IP address

您可以将加密 dll 的当前 public 接口设置为仅供内部使用。 然后,使用 InternalsVisibleTo 属性,您可以指定一个或多个可以实际看到那些内部接口方法的特定程序集。

这将允许您限制对您的加密库的访问。

此处参考:InternalsVisibleToAttribute Class

编辑 1

唯一的缺点是如果恶意用户要反编译您的加密 dll。 虽然您可以使其难以实现,但您无法在 .Net 中完全避免它。

此外,您没有提及风险级别(internal/corporate 应用程序,public 仅可用应用程序等),这使得提供最佳 回答相当困难。

(我说 最佳 答案,因为不能保证任何密码学:))

如果它是公开可用的应用程序,那么您最好避免在 winform 应用程序本身中存储任何 SQL 连接字符串详细信息。

相反,托管 winform 将通过其进行通信的 Web 服务。
这将确保恶意用户无法获取您的 SQL 连接详细信息(至少不能从 winform 应用程序或关联的 dll 中获取)并允许您将 SQL 服务器隐藏在远离网络的地方。

有很多方法可以保护 Web 服务,使其只能由 "approved" 客户端访问。 (用户身份验证令牌等)