情况1 - 将服务器连接到数据库:
它总是说密码不应该以纯文本形式存储,但要连接到mysql数据库需要密码,在纯文本中似乎......我猜这是最好的解决方案是以加密形式存储它,根据需要在我的应用程序中解密它然后从内存中擦除它(Windows中的SecureZeroMemory我猜这样编译器无法优化它)。
情况2 - 用户从远程计算机登录服务器:
至于用户密码,我的计划是永远不会真正存储原始密码。
相反,我会为每个用户存储一个随机生成的“salt”,然后在其前面加密码然后哈希,这似乎是一种相对常见的方式。但是我此时没有可用的SSL连接,所以我猜测可以拦截纯文本密码,这对此有什么好处?
什么是好的算法(链接到C / C ++实现,如果你有它们也会很方便)这样做,在网上看一下它们的100个?
编辑:
如果我获得SSL,以下是安全的(假设使用了强哈希算法),还是应该使用不同的方法?
答案 0 :(得分:1)
你是对的,如果你没有使用SSL,那么可以拦截密码。
通常的做法是永远不要解密用户的密码,因此请将其存储在哈希值中,当用户输入密码时,您将添加盐并对其进行哈希处理,并将其与存储的哈希密码进行比较。这将允许您永远不会拥有密码的解密版本。
您真的应该考虑保护连接,以便在用户输入密码时密码是安全的。
更新以回答编辑过的问题:
如果您使用SSL保护通信,您仍然可以使用任何数量的额外安全措施,包括哈希密码。为了增加安全性,最好记住您存储的密码应该用盐进行哈希处理。该盐应该保持安全,除了您的应用之外,任何地方都不能进入。这样,当用户提交密码时,您只需添加salt和hash,然后将该版本与存储的版本进行比较。
答案 1 :(得分:1)
将服务器连接到数据库
只是将数据库密码存储在服务器中 - 加密与否 - 是个坏主意。当然,很明显将它存储在纯文本中。如果你只是加密存储,服务器仍然需要密钥来解码它。在服务器代码中找到密钥通常不是很难。最好的解决方案是让用户启动服务器输入密码并将其存储在任何地方。或者 - 甚至可能更好 - 您可以存储所有敏感信息(例如数据库用户,密码等) - 加密并让用户启动服务器输入主密钥来解密此信息。
将用户连接到服务器
这确实是一个难题,容易搞砸。关于我绝对建议阅读的主题的this great article article引用。
不,真的。使用别人的密码系统。不要建立自己的。
一个好的解决方案可能是使用Secure Remote Password Protocol。
答案 2 :(得分:1)
情况1 - 将服务器连接到数据库
这里没有一个简单的答案。为了连接,服务器需要密码(或对称密钥,或私钥或其他)。它必须从磁盘或一些外部手段(如管理员在启动时键入它)获取它。添加一些间接,例如加密主密码下的所有敏感内容,可以增加一些便利,但不会改变这种情况。
通常,可以将密码或密钥放在服务器上的文件中。如果这样做,请确保在文件上设置权限,以便只有需要它的用户才能访问它。这是让您的系统上的不同进程作为不同用户运行,并为每个进程设置单独的角色/帐户和密码的绝佳理由。
情况2 - 用户从远程计算机登录服务器
我想,你正朝着正确的方向前进。你所要求的是一种安全的身份验证协议。如果尝试进行此类攻击,您需要提供相互身份验证并防止中间人攻击失败的攻击。当然有很多可供选择。
同样值得考虑的是,您的身份验证是否应基于“您知道的事情”(密码)或“您拥有的东西”(公钥/私钥)进行操作。根据你的问题假设我们要找的是密码,我喜欢的两个是SRP和Kerberos。
早些时候提到过SRP,并没有得到应有的重视。 SRP的优势在于它不需要服务器知道密码,密钥或攻击者可以用来获取访问权限的任何内容。如果您使用SRP进入正确配置的服务器并窃取了所有数据,那么在您有可能用来冒充用户的任何内容之前,您仍然需要单独对每个密钥进行字典攻击。我也喜欢Kerberos,因为它受到大量软件的支持(我知道Postgres支持它,我只发现mysql提到不支持任何良好的身份验证技术)并且有一个“门票”系统,提供单个标志能力。 Kerberos需要一些其他技术来帮助加强其初始身份验证交换,而SRP对此非常有用,但我不确定他们是否已经这样做了。关于它的一些事情,我认为KDC(密钥服务器)是有状态的。
Kerberos的弱点是你必须更加警惕存储密钥的服务器。虽然它不以明文形式存储密码,但它确实存储了密钥,这些密钥基本上是密码的散列版本。虽然客户端在进行身份验证时并没有完全发送密码或密钥(毕竟这是一个真正的身份验证协议),但它确实使用散列密码作为密钥,因此任何知道算法的人都知道关键也可以这样做。我们说服务器存储“密码等效”。因此,所有手册都告诉管理员将kerberos服务放在他们自己独立的锁定盒子上,以尽量减少损害其内容的可能性。
好消息是,一旦你开始进行强大的身份验证交换,其他好东西通常都会免费提供。最终,双方共享一个共同的“秘密”,可以在会话期间使用一次,从不通过网络发送,也不会被第三方所知。想要加密吗?有钥匙,都准备好了。这正是RFC 5054中定义SRP安全SSL的方式。
答案 3 :(得分: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对密码进行哈希处理。问题是如何在客户端和服务器之间共享salt字符串?一种可能性是使用会话变量。然后使用会话变量在服务器上取消密码。这意味着中间的人需要知道另一条信息才能理解密码。不像SSL那么安全,但可能是针对休闲网络嗅探器的额外防御层。
我还可以想象一种哈希方案,它链接到某种验证码系统,用于在通过网络发送之前对本地客户端上的密码进行加密。客户端将通过填写验证码为salt字符串提供文本。你可以在最后查找它。
主要担心的是中间人不理解明文密码。
应该使用SSL,但在无法使用SSL的情况下,上述技术可能会有用。
答案 4 :(得分:0)
较新的MySQL使用散列密码,因此您不必担心中间人。
如果您担心配置文件中存储的密码,可以使用密码加密配置文件。但是,问题是您必须输入密码才能启动应用程序。
我在15年前写过类似的应用程序。那时候,PGP是我的选择。我甚至不确定它还在附近。