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

How to encrypt a password for saving it later in a database or text file?

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

复制

Encrypting/Hashing plain text passwords in database

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

编辑:我正在保存密码供以后使用。我需要解码并使用它登录。它不必是超级安全的,它只是需要不可读的人眼,并难以用一个微不足道的脚本解码。


StackOverflow阅读器不知道如何编写安全密码方案,您也不知道。如果你想这样做,可以用纯文本来节省时间。关于彩虹表:你需要知道的关于安全密码方案:

Rainbow tables are easy to beat. For
each password, generate a random
number (a nonce). Hash the password
with the nonce, and store both the
hash and the nonce. The server has
enough information to verify passwords
(the nonce is stored in the clear).
But even with a small random value,
say, 16 bits, rainbow tables are
infeasible: there are now 65,536
"variants" of each hash, and instead
of 300 billion rainbow table entries,
you need quadrillions. The nonce in
this scheme is called a"salt".

Cool, huh? Yeah, and Unix crypt —-
almost the lowest common denominator
in security systems —- has had this
feature since 1976. If this is news to
you, you shouldn’t be designing
password systems. Use someone else’s
good one.

对.net和mono使用bcrypt-strong密码散列。这是一个干净的.cs文件,随着密码破解计算机速度的加快,它将继续满足您的需求。


bcrypt-用于.net和mono的强密码哈希


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

无论如何,这并不完美,但99.999%的人都是这样存储密码的。

如果你想辩称如果用户丢失/忘记了密码,你想把它提供给他们,那么请不要这样做。给他们发一个临时密码(你把它存储在数据库中),让他们在第一次登录时更改密码。


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


如果您使用加密来安全地存储密码,那么您也需要将加密"密钥"存储在某个地方。这将是"弱链接",因为如果有人获得加密密钥,他们将能够解密加密的密码。

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

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

有关详细信息,请参阅以下链接:用salt散列密码

对于加密(如果您需要使用它),我将使用rijndael(aes)。


如果您需要解密密码以备日后使用,并且密码不必是超级安全的,请使用以下方法:

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

它有很好的文档记录,很容易理解。


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

如果您只需要使用他们的密码进行身份验证,而不需要其他任何方法。

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

  • 在将密码从客户机传输到服务器时,请确保连接已加密。这将防止它被嗅出。这对于Web应用程序来说非常简单,因为Web服务器正在为您做繁重的工作。如果不是这样的话,它会变得更加棘手,并且是整个其他问题的主题。

  • 选择实体哈希算法以防止冲突。我建议使用sha-256,即使它提供的结果比sha1或md5更大。这里是微软关于使用他们的algorythm实现的参考。

  • 使用rainbowtable盐化密码以防止攻击(即使用预先计算的哈希和相关的明文密码在大表中查找密码)。这里的答案(位于您的问题中)给出了关于如何使用Python的好的伪代码。这里还有一个很好的.NET代码示例。

  • b.如果您需要能够读取每个用户的密码,而不是验证用户身份。

    如果我们只讨论在一台计算机(服务器)上存储密码(或任何敏感信息),那么这种情况就很容易了。如果是这样的话,使用Microsoft数据保护API将是一个很好的解决方案,因为它与计算机以及(取决于您的工作方式)应用程序运行所用的用户绑定在一起,并为您处理最差的作业(创建、存储和使用密钥)。您可以在这里找到一些来自Microsoft的代码引用。如果您在多个系统上需要它,并且不愿意在您的应用程序上安装的每个系统上输入密码,那么事情会变得更加复杂,因为您需要从头开始实现很多密码。这将是我想的另一个问题的主题。


    就我个人而言,我会使用单向加密的东西——MD5、SHA1等等……

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


    是否需要再次加密?否则,使用hashfunction对其进行加密,并使用相同的hashfunction对用户提供的密码进行加密,并查看哈希值是否相等。

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


    您真的需要能够检索密码本身吗?如果您存储密码是为了验证某人(或某物)的身份,那么您应该散列它(使用salting),然后将散列与希望进行身份验证的一方提供的密码散列进行比较。

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


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

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


    像ocdecio一样,我也会使用三倍体,将盐保存在数据库中。我的密钥通常是硬编码的,但是每个加密项的salt都应该改变。


    下面是一篇带.NET示例代码的字符串加密文章

    http://www.devarticles.com/c/a/vb.net/string使用Visual Basic进行加密-.net/3/

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


    简要地:

    得到一个大的随机数,你将保持私密,只有你的应用程序代码将有权访问。

    使用类似sha1的加密算法对密码+随机数进行加密,大多数编程语言都有一个加密框架。

    存储哈希密码。

    稍后,当您想要检查输入的密码时,您可以重新刷新用户输入,并将其与"实际上"不可加密的存储密码进行比较。