Asp.net 我应该如何存储用于自动身份验证的用户名/密码?

Asp.net 我应该如何存储用于自动身份验证的用户名/密码?,asp.net,database,security,authentication,Asp.net,Database,Security,Authentication,我工作的一个组织每天都会使用一些不同的网站。我被要求开发一个web应用程序(使用ASP.NET),该应用程序可以访问/合成这些信息,并将其显示在一个位置。不幸的是,其中一个网站不支持OAuth或任何类似的东西,因此我需要将其登录凭据存储在数据库中 我的第一个想法是使用他们对我的站点的凭据作为密钥来加密他们对远程站点的凭据。例如:Bob使用密码hunter2登录到我的网站。使用该密码,我解密Bob在www.example.com上的凭据,并以Bob的身份登录。因为我不需要访问example.com

我工作的一个组织每天都会使用一些不同的网站。我被要求开发一个web应用程序(使用ASP.NET),该应用程序可以访问/合成这些信息,并将其显示在一个位置。不幸的是,其中一个网站不支持OAuth或任何类似的东西,因此我需要将其登录凭据存储在数据库中

我的第一个想法是使用他们对我的站点的凭据作为密钥来加密他们对远程站点的凭据。例如:Bob使用密码hunter2登录到我的网站。使用该密码,我解密Bob在www.example.com上的凭据,并以Bob的身份登录。因为我不需要访问example.com,除非Bob在我的网站上,我可以在他完成解密后丢弃解密的凭据


我的假设是,仅仅使用hunter2(或Bob的密码)是不够的,而且有一种“标准”的方法,我在Google或Stack Overflow上找不到。

无论你采取什么方法,都会有问题,让你怀疑自己。您需要根据您的环境平衡解决方案,并查看最适合的解决方案

您的应用程序的每个用户都会在远程系统上拥有一个帐户吗?您的系统如何对用户进行身份验证?您的应用程序是否在受信任的环境中运行(如公司网络)

我编写了一个类似的应用程序,在一个拥有自己用户名和密码的内部系统前运行。我的应用程序使用Windows集成身份验证来确定用户是谁。然后它向远程系统请求密码并使用硬编码密钥加密该值,然后将该值存储在数据库中。然后,它可以检索该值,对其进行解密,并在需要时将其提供给远程系统


现在,在一个不受信任的环境中,有人可以获取我的二进制文件&找出它们的密钥是什么&获取所有密码。那太糟糕了。但在企业网络中,如果他们这样做了,他们应该来为我工作。

无论你采取什么方法,都会有让你怀疑自己的问题。您需要根据您的环境平衡解决方案,并查看最适合的解决方案

您的应用程序的每个用户都会在远程系统上拥有一个帐户吗?您的系统如何对用户进行身份验证?您的应用程序是否在受信任的环境中运行(如公司网络)

我编写了一个类似的应用程序,在一个拥有自己用户名和密码的内部系统前运行。我的应用程序使用Windows集成身份验证来确定用户是谁。然后它向远程系统请求密码并使用硬编码密钥加密该值,然后将该值存储在数据库中。然后,它可以检索该值,对其进行解密,并在需要时将其提供给远程系统


现在,在一个不受信任的环境中,有人可以获取我的二进制文件&找出它们的密钥是什么&获取所有密码。那太糟糕了。但是在公司网络上,如果他们这样做了,他们应该会来为我工作。

您已经可以访问用户的明文二级密码,因此无论您是否丢弃加密密钥,您仍然要对其安全负责。在处理密码时请记住这一点

如果使用用户自己的密码进行加密,则会将其所有辅助密码的强度降低到主密码的强度。这可能是不好的,因为a)用户密码已经非常弱了(我知道,为什么我们一开始还要麻烦呢?)和b)即使使用最强的密码,它仍然无法与可靠随机256位AES密钥的强度相匹配


我的建议是考虑使用一个单独的AES密钥来加密他们的明文二级密码。然后,保护好AES密钥。相反,有一个加密多个子密钥的根AES密钥是有意义的,每个用户一个子密钥。我想,您必须进行风险分析。

您已经可以访问用户的明文二级密码,因此,无论您是否丢弃加密密钥,您仍然要对其处于明文状态时的安全负责。在处理密码时请记住这一点

如果使用用户自己的密码进行加密,则会将其所有辅助密码的强度降低到主密码的强度。这可能是不好的,因为a)用户密码已经非常弱了(我知道,为什么我们一开始还要麻烦呢?)和b)即使使用最强的密码,它仍然无法与可靠随机256位AES密钥的强度相匹配


我的建议是考虑使用一个单独的AES密钥来加密他们的明文二级密码。然后,保护好AES密钥。相反,有一个加密多个子密钥的根AES密钥是有意义的,每个用户一个子密钥。我想您必须进行风险分析。

如果您无法避免将密码存储在服务器上,那么使用用户的“主”密码(例如“hunter2”)进行加密是最佳选择。在服务器受损的情况下,没有其他方法提供保护。现在。。。您获得的保护程度完全取决于用户主密码的复杂性。最后,我将对该方案的安全性进行分析,但在此之前,让我回顾一下要避免的陷阱

首先,我假设你已经知道了,但是-。好吧,假设不存在了

不要使用用户的实际密码作为加密功能的密钥。

考虑一下如果您这样做可能会发生什么:如果攻击者成功下载了您的整个用户表,并使用加密的example.com密码,该怎么办?我们都知道用户选择的密码很容易猜测。如何阻止攻击者重复解密加密的example.com密码、尝试作为密钥、丢弃任何看起来不像密码的结果(即,解密的结果不会出现在单词列表中)?AES是。虽然不是苹果对苹果的比较,但是
public static byte[] DeriveKey(int keyBitSize, string password, byte[] salt) {
    const int iterations = 1<<12; // Once set, any change will break decryption.
    using (var kdf = new Rfc2898DeriveBytes(password, salt, iterations)) {
        return kdf.GetBytes(keyBitSize);
    }
}