我有一个客户正在运行来自多个帐户的信息聚合器。数据库需要将用户名和密码存储到其他网站,以便稍后脚本可以使用该方式登录这些网站以检索数据。
我认为我们可以对它们进行哈希存储,而不是将它们存储为纯文本。显然,如果有人可以访问代码和数据库,他们仍然可以访问纯文本版本,但如果他们只有一个或另一个,则不能。
有更好的想法吗?
我有一个客户正在运行来自多个帐户的信息聚合器。数据库需要将用户名和密码存储到其他网站,以便稍后脚本可以使用该方式登录这些网站以检索数据。
我认为我们可以对它们进行哈希存储,而不是将它们存储为纯文本。显然,如果有人可以访问代码和数据库,他们仍然可以访问纯文本版本,但如果他们只有一个或另一个,则不能。
有更好的想法吗?
如果您的系统要求用户输入密码,您可以使用该密码生成密钥来加密/解密其他网站的密码。
这样,您需要您的用户输入该密码才能解密您存储在数据库中的密码。
这里有更详细的流程:
您可以通过多种方式对此进行优化。例如:在计算 SHA 哈希之前对密码进行加盐。
作为这种加盐的实际示例,Michael建议使用PBKDF2(使用HMAC -<a href="https://en.wikipedia.org/wiki/SHA-2" rel="nofollow noreferrer">SHA-256 作为其两个参数伪随机函数)。
其他增强:存储密钥的加密版本,以允许您的用户更改自己的密码,而无需重新加密他的所有密码......等等......
混淆实际上给你带来了什么?时间。毕竟数据就在那里,你自己使用它的方案也是如此。有人弄清楚你的计划是什么只是时间问题。这一切都取决于您的偏执程度以及对您感到满意的风险程度的评估。特别是,如何存储任何凭据应取决于谁有权访问运行数据库的机器。
最终,橡胶必须上路,所以继续前进并征服。不要完全敲打混淆。只需确保将其与明智的做法相结合。
如果您可以从第三方帐户生成 API 密钥,这将使您能够撤销对帐户的访问权限,而无需关闭所有潜在的应用程序。许多服务都有这些类型的 API 密钥(Google、Twitter、StackExchange、Facebook 和许多其他服务)。
您只需设置一个“应用程序”,然后使用消费者密钥和秘密以及访问令牌和访问秘密。机器只需要存储这些凭据。如果发生妥协,您只需撤销该组密钥。此外,这些允许您指定每个帐户的权限。
当用户登录时,您才能解锁他们的密码集。为此,您将根据适当的散列方案生成一个密钥,并在密钥之前进行几个散列步骤进行验证检查。
您始终可以使用一个密钥加密凭据。然后,您只有一个要保护的密钥(保护所有其他秘密)。然后,您必须在访问其他凭据之前进行解密。
在 Linux 上,使用gnome-keyring。然后您可以进行简单的 Create-Read-Update-Delete 调用,将其视为密码数据库。Gnome 密钥环基于 PKCS#11 标准。
gnome-keyring 有一个用于保存到密钥环和检索项目的API。
/* A callback called when the operation completes */
static void
found_password (GnomeKeyringResult res, const gchar* password, gpointer user_data)
{
/* user_data will be the same as was passed to gnome_keyring_find_password() */
// ... do something with the password ...
/* Once this function returns |password| will be freed */
}
static void
find_my_password()
{
gnome_keyring_find_password (GNOME_KEYRING_NETWORK_PASSWORD, /* The password type */
found_password, /* callback */
NULL, NULL, /* User data for callback, and destroy notify */
"user", "me",
"server", "gnome.org",
NULL);
}
在 Windows 7+ 上,使用“加密文件系统”(EFS) 功能。所有文件都使用证书加密,而证书又受您的 Windows 密码保护。
不过,不要让这让你产生一种虚假的安全感。如果这是运行它的服务器,如果有人获得了对该盒子的网络访问权限,那么他们自己也可以访问密钥环数据。
您能否设置一台机器,使用公钥和私钥对授予对凭据或解锁密钥的访问权限?
如果您对用户名和密码进行哈希处理,您将无法取回它们。哈希被设计为单向函数。
您可以对数据进行编码以进行混淆,但我不建议这样做。
如果您对信息进行哈希处理,则以后无法检索它。如果加密它,则需要将密钥存储在某处。除了物理上限制对数据库的访问之外,没有可靠的方法来消除恶意使用数据的可能性。
散列可以以所有可预见的方式阻止对原始数据的使用。但是,您需要使用数据。像 SHA-256 这样的密码散列被设计成在计算上很难(不制作大小不合理的查找表)来找到你最喜欢的散列函数m
在H(m)
哪里。H
如果您走加密路线,则需要存储加密密钥,它可能会被破坏或至少用作解密预言机。您可以创建一个为您进行解密的服务代理,并使用客户端和服务器身份验证证书来确保安全。但是,如果有人入侵了授权客户端,那么您在入侵和检测到帐户可能被入侵之间有一个时间窗口。但是这种方法使您可以灵活地撤销证书并立即拒绝服务器访问,即使您不再有权访问受感染的客户端。
我建议设置一个仅可通过直接连接(在同一物理交换机上)使用的远程服务,该服务向客户端进行身份验证并要求所有客户端进行身份验证。如果客户受到威胁,也许限制它可以进行的查询数量也有助于防止滥用。该服务将需要检查每个请求的证书吊销。
此服务还需要连接到远程日志记录工具,该工具将用于独立审核系统。此日志服务需要再次验证客户端并通过客户端验证自身。日志服务接收数据并将其附加到日志中,它不允许修改或删除。当它接收到一个日志条目时,它会对一个带有时间戳的日志条目进行数字签名并将其输入到审计容器中。
这类似于证书颁发机构如何设置他们的书面记录来审核证书颁发,以便为妥协提供可能的最佳恢复模型,因为实际上防止妥协是不可能的。