1

情况1 - 将服务器连接到数据库:
它总是说密码不应该以纯文本形式存储,但是连接到mysql数据库需要密码,在纯文本中似乎......我猜是最好的解决方案这是以加密形式存储它,根据需要在我的应用程序中解密,然后从内存中删除它(我猜是 Windows 中的 SecureZeroMemory,所以编译器无法优化它)。

情况 2 - 用户从远程计算机登录服务器:
至于用户密码,我的计划是根本不实际存储原始密码。相反,我将存储一个随机生成的“盐”,为每个用户在密码前加上前缀,然后对其进行哈希处理,这似乎是一种相对常见的方式。但是我此时没有可用的 SSL 连接,所以我猜测纯文本密码可能会被截获,有什么好的解决方案?

什么是好的算法(如果你有的话,链接到 C/C++ 实现也会很方便),网上一看就会有 100 个?

编辑:
如果我获得 SSL,以下内容是否安全(假设使用了强哈希算法),还是应该使用不同的方法?

  1. 客户端请求用户名加盐
  2. 客户端在密码前加上盐,然后在将哈希发送到服务器之前对其进行哈希处理
  3. 服务器将收到的哈希值与服务器上该用户名的哈希值进行比较
4

5 回答 5

1

将服务器连接到数据库

仅将数据库密码存储在服务器中(无论是否加密)都是一个坏主意。当然,很明显将其存储为纯文本。如果你只是将它加密存储,服务器仍然需要密钥来解码它。在服务器代码中找到密钥通常并不难。最好的解决方案是让启动服务器的用户输入密码并将其存储在任何地方。或者——甚至可能更好——你可以存储所有敏感信息——例如数据库用户、密码等等——加密并让启动服务器的用户输入一个主密钥来解密这些信息。

将用户连接到服务器

这确实是一个难题,而且很容易搞砸。我绝对推荐阅读这篇关于该主题的精彩文章的引述。

不完全是。使用别人的密码系统。不要建立自己的。

一个好的解决方案可能是使用安全远程密码协议

于 2009-08-04T13:26:53.533 回答
1

你是对的,如果你不使用 SSL,那么密码可以被拦截。

通常的做法是从不解密用户的密码,因此将其存储在使用盐的散列中,当用户输入他们的密码时,您将添加盐并对其进行散列,并将其与存储的散列密码进行比较。这将允许您永远拥有密码的解密版本。

您确实应该考虑保护连接,以便在用户输入密码时密码是安全的。

更新以回答已编辑
的问题:如果您使用 SSL 保护通信,您仍然可以使用您喜欢的任何数量的额外安全措施,包括对密码进行哈希处理。为了增加安全性,最好记住您存储的密码应该使用盐进行散列存储。盐应该保持安全,除了您的应用程序外,永远不能在任何地方访问。这样,当用户提交密码时,您只需添加盐和哈希,然后将该版本与存储的版本进行比较。

于 2009-08-04T12:54:27.913 回答
1

情况 1 - 将服务器连接到数据库

这里没有一个简单的答案。为了连接,服务器需要密码(或对称密钥,或私钥或其他)。它必须从磁盘或某些外部方式(例如管理员在启动时键入它)获取它。添加一些间接性,例如在主密码下加密所有敏感内容,可以增加一些便利,但不会改变这种情况。

通常,可以将密码或密钥放在服务器上的文件中。如果这样做,请确保设置文件的权限,以便只有需要它的用户才能访问它。这是让系统上的不同进程以不同用户身份运行并为每个用户设置单独角色/帐户和密码的绝佳理由。

情况 2 - 用户从远程计算机登录服务器

我认为你正朝着正确的方向前进。听起来您要求的是安全的身份验证协议。您需要一个提供相互身份验证并通过在尝试此类攻击时失败来防止中间人攻击的工具。当然有很多选择。

同样值得考虑的是您的身份验证是否应该基于“您知道的东西”(密码)或“您拥有的东西”(公钥/私钥)进行操作。根据您的问题假设我们正在寻找的是密码,我喜欢的两个是 SRP 和 Kerberos。

SRP 前面提到过,但几乎没有得到应有的关注。SRP 的优点是它不需要服务器知道密码、密钥或任何攻击者可以用来获取访问权限的东西。如果您使用 SRP 闯入正确配置的服务器并窃取了所有数据,那么您仍然需要对每个键单独执行字典攻击之类的操作,然后才能使用任何可以用来模拟用户的东西。

我也喜欢 Kerberos,因为它受到大量软件的支持(我知道 Postgres 支持它,我只发现 mysql 不支持任何良好的身份验证技术)并且有一个提供单点登录功能的“票证”系统。Kerberos 需要一些其他技术来帮助加强其初始身份验证交换,而 SRP 对此非常有用,但我不确定他们是否已经这样做了。我认为它使 KDC(密钥服务器)有状态。

Kerberos 的弱点是您必须更加警惕存储密钥的服务器。虽然它不以明文形式存储密码,但它确实存储了密钥,这些密钥本质上是密码的散列版本。虽然客户端在身份验证时不会直接发送密码或密钥(毕竟这是一个真正的身份验证协议),但它确实使用散列密码作为密钥,因此任何知道算法并知道的人钥匙可以做同样的事情。我们说服务器存储“密码等价物”。因此,所有手册都告诉管理员将 kerberos 服务放在自己单独的、锁定的盒子上,以最大限度地减少损害其内容的机会。

好消息是,一旦你确定了一个强大的身份验证交换,其他好东西通常会免费掉出来。您最终会得到双方共享一个共同的“秘密”,该“秘密”可以在会话期间使用一次,永远不会通过网络发送,并且第三方无法知道。想要加密?有钥匙,一切准备就绪。这正是 RFC 5054 中定义 SRP 安全 SSL 的方式。

于 2010-05-26T07:54:28.940 回答
0

不确定这是否是您要求的。但是一个使用内置 sha1 函数的简单 PHP 示例:

// Check the hashed password from the database
if (sha1($salt.$password) == $providedPassword)
{
    // User is authenticated
    return TRUE;
}
else
{
    // User is not authenticated    
    return FALSE;
}

您可以做的一件事是在通过网络发送密码之前使用 javascript 对密码进行哈希处理。问题是客户端和服务器之间如何共享盐字符串?一种可能性是使用会话变量。然后使用会话变量在服务器上取消密码。这意味着中间的人需要知道另一条信息才能理解密码。不如 SSL 安全,但可能是针对临时网络嗅探器的额外防御层。

我还可以想象一个哈希方案链接到某种验证码系统,用于在通过网络发送之前在本地客户端上加盐密码。客户端将通过完成验证码来提供盐字符串的文本。你可以自己查一下。

主要担心的是中间人不理解纯文本密码。

应该使用 SSL,但在 SSL 不可行的情况下,上述技术可能很有用。

于 2009-08-04T13:25:34.343 回答
0

较新的 MySQL 通过网络使用散列密码,因此您不必担心中间人。

如果您担心存储在配置文件中的密码,可以使用密码对配置文件进行加密。但是,问题是您必须输入密码才能启动应用程序。

我在 15 年前写了一个类似的应用程序。那时,PGP 是我的选择。我什至不确定它是否还在。

于 2009-08-04T13:30:15.057 回答