如何加密密码以便以后将其保存在数据库或文本文件中?

时间:2009-02-12 13:28:49

标签: c# .net security

我希望我的应用程序保存在数据库或文本文件中加密的密码。 假设数据库或文本文件可以由任何人打开,我该怎么做呢?

复制

  

Encrypting/Hashing plain text passwords in database

不重复 我要求特定于.NET的代码

编辑:我正在保存密码供以后使用。我需要对其进行解码并使用它进行登录。 它不一定非常安全,它只需要人眼不可读,并且难以用琐碎的脚本解码。

14 个答案:

答案 0 :(得分:23)

StackOverflow读者不知道如何编写安全密码方案,您也不知道。如果您打算这样做,请坚持使用纯文本来节省时间。来自Enough With The Rainbow Tables: What You Need To Know About Secure Password Schemes

  

彩虹桌很容易被击败。对于   每个密码,生成一个随机的   数字(随机数)。哈希密码   与nonce,并存储两者   哈希和随机数。服务器有   足够的信息来验证密码   (nonce存储在clear中)。   但即使随机值很小,   比方说,16位,彩虹表是   不可行:现在有65,536   每个哈希的“变体”,而不是   3000亿彩虹表条目,   你需要四倍。 nonce in   这种方案被称为“盐”。

     

很酷,对吧?是的,还有Unix地穴 -   几乎是最低的共同点   在安全系统 - 已经有这个   自1976年以来的特色。如果这是新闻   你,你不应该设计   密码系统。使用别人的   好的。

使用BCrypt - .NET和Mono的强密码哈希。它是一个干净利落的.cs文件,随着密码破解计算机变得更快,它将继续满足您的需求。

答案 1 :(得分:15)

BCrypt - .NET和Mono的强密码哈希

答案 2 :(得分:9)

三重DES是一种方法,只要您的意思是“我的系统需要能够调用的密码才能访问资源”。如果您的意思是密码是用户需要能够访问您的系统的东西,可能不需要加密,只需要哈希即可。存储散列密码值时,对于具有直接数据库访问权限的任何人都没用,但仍可用于身份验证。您所做的就是将存储的哈希值与传入密码的哈希值进行比较。如果匹配,则授予访问权限。

无论如何,它并不完美,但99.999%的人存储密码的方式。

如果你想争辩说如果他们丢失/忘记了密码,你想要将密码提供给用户,那么请不要。使用临时密码(您在数据库中存储哈希值)发出它们,并让它们在首次登录时进行更改。

答案 3 :(得分:8)

Data Protection API与用户或机器商店一起使用(例如,您的程序/数据库服务器在每个帐户下运行的密钥与每台机器的一个密钥不同)。这将帮助您稍后解码密码,您不必记住或存储任何加密密钥。它的缺点是,当您重新安装系统/删除帐户时,您无法恢复数据,我相信。

答案 4 :(得分:4)

如果使用加密来安全存储密码,则还需要在某处存储加密“密钥”。这将是“弱链接”,因为如果有人掌握加密密钥,他们将能够解密加密密码。

由于这是我们在这里讨论的密码,更好的解决方案是使用单向散列。您在用户首次创建密码时散列密码(最好使用salt值进行散列)并存储生成的散列值。由于散列是单向的,因此没有人可以将散列转换为原始纯文本值。

要检查用户密码是否正确,您只需向用户询问明文密码,再次对其输入进行哈希处理,并将得到的哈希值与您存储的哈希值进行比较(当然要考虑盐)。如果两个哈希值相同,则用户输入了正确的密码。

有关详细信息,请参阅以下链接: Hashing Password with Salt

对于加密(如果您需要使用),我会使用Rijndael (AES)

答案 5 :(得分:2)

根据您的问题,我可以看到两种方法,具体取决于您存储密码的原因。

:一种。如果您只需要使用他们的密码进行身份验证而不需要其他任何操作。

在这种情况下,使用不可逆的算法(Hashing)将是您的最佳选择。您需要确定以下几点:

  1. 将密码从客户端传输到服务器时,请确保连接已加密。这样可以防止它被嗅出来。这对Web应用程序来说非常简单,因为Web服务器正在为您做繁重的工作。如果不是它会引起很多琐事并成为另一个问题的主题。

  2. 选择实体哈希算法以防止冲突。我建议使用SHA-256,即使它确实提供了比SHA1或MD5更大的结果。 Microsoft对使用algorythm实现的引用是here

  3. 使用rainbowtable填充密码以防止攻击(即使用预先计算的哈希和明文中的相关密码查找大表中的密码)。答案here(位于您的问题中)在Python中提供了关于如何执行此操作的良好伪代码。 .NET代码here也有一个很好的例子。

  4. <强> B中。如果您需要能够为每个用户读取密码,除了对用户进行身份验证之外的其他目的。

    如果我们只谈论在一台计算机(服务器)上存储密码(或任何类型的敏感信息),这种情况很容易。如果是这种情况,使用Microsoft Data Protection API将是一个很好的解决方案,因为它与该计算机绑定并且(取决于您的工作方式)运行应用程序的用户并为您处理最糟糕的工作(创建,存储和使用密钥)。您可以从Microsoft here中找到一些代码参考。如果您需要在多个系统上使用它并且不愿意在您在应用程序上安装的每个系统上输入密码,那么事情会变得复杂得多,因为您需要从头开始实施大量的系统。那将是我想到的另一个问题的主题。

答案 6 :(得分:2)

如果您需要解密密码以供以后使用,并且它不必是超级安全的,请使用此处的方法:

http://support.microsoft.com/kb/307010

记录良好,易于理解。

答案 7 :(得分:1)

你需要再次加密吗?否则使用哈希函数对其进行加密并使用相同的哈希函数加密用户给出的密码,并查看哈希值是否相等。

不使用双向加密的原因是无法解密密钥 - 因为好的哈希函数会发生冲突。

答案 8 :(得分:1)

就个人而言,我会使用具有单向加密功能的东西 - MD5,SHA1等......

您可以将FormsAuthentication类与其HashPasswordForStoringInConfigFile方法一起使用。验证用户时,加密输入的密码并将其与存储的版本进行比较。

答案 9 :(得分:0)

像ocdecio一样,我会使用TripleDes,我也会将盐保存在数据库中。对我来说,关键通常是硬编码,但每个加密项目的盐应该会改变。

答案 10 :(得分:0)

如果您只需要内部身份验证过程的密码,则不应保存实际密码,而是保存此密码的hash。当您需要检查密码是否有效时,您必须在提供的密码上运行散列函数,并将其与存储在数据库/文件中的散列进行比较。您永远无法从哈希中找到原始密码。

如果您需要保留原始密码,则必须对其进行加密。例如,如果您有一个写入密码(公钥)的进程和另一个读取密码的进程(私钥),您可以使用public key infrastructure

答案 11 :(得分:0)

您真的需要能够自己检索密码吗?如果您为了验证某人(或某些东西)而存储密码,则应该将其哈希(使用salting),然后将该哈希值与希望进行身份验证的一方提供的密码的哈希值进行比较。

另一方面,如果您需要存储密码以便能够检索密码并在以后将其提供给其他某些身份验证服务,那么您可能希望将其加密存储。在这种情况下,请使用任何体面的对称加密算法,例如TripleDES或AES或Blowfish。

答案 12 :(得分:-3)

简言之:

获取一个大的随机数,您将保密,只有您的应用程序代码才能访问。

使用SHA1等加密算法加密密码+随机数,大多数编程语言都有加密框架。<​​/ p>

存储哈希密码。

稍后当您想要检查输入的密码时,您可以重新输入用户输入并与“虚拟”无法解密的存储密码进行比较。

答案 13 :(得分:-3)

这是一个带有示例代码.NET

的字符串加密文章

http://www.devarticles.com/c/a/VB.Net/String-Encryption-With-Visual-Basic-.NET/3/

没有必要使用任何花哨的东西,因为任何具有一点技巧和决心的人都会打破它。