Castle ActiveRecord/NHibernate - 密码加密或散列

Castle ActiveRecord/NHibernate - 密码加密或散列

问题描述:

使用密码的正确方法是什么?您不想以明文形式存储在数据库中? NHibernate/Castle ActiveRecord有哪些选项?Castle ActiveRecord/NHibernate - 密码加密或散列

更新: 我对其他人如何用NHibernate/Castle ActiveRecord处理这个问题感兴趣。 并且如果有任何内置NHibernate或Castle ActiveRecord的。

您应该加密或散列密码。散列更安全一些(取决于当然的算法)。因为它不可逆转;但是,由于您可以拥有检索密码选项,因此加密功能可以更加实用。随着哈希,你必须生成一个新的密码..

至于nHibernate /城堡,你应该处理你的业务对象恕我直言,从持久性机制分离算法。

最好的方法是使用UserType。 Here's one实现透明密码加密。

我会将这样的常见问题复制到ActiveRecord wiki

哈希密码。不要加密 - 它很复杂和/或不安全。在普通的业务线应用程序或网站中,根据其他可验证标准重置密码是不可行的。我不知道你是否熟悉哈希密码的原理,所以我会从基础知识中解释...

当用户最初选择他们的密码时,你运行一个文本上的哈希算法。这会产生一个签名 - 如果将相同的字符串输入哈希算法,则总是会生成一个输出。关键是你不能从哈希中返回密码(因此是单向的)。然后您存储散列,而不是密码。当用户返回时,他们必须再次输入密码,然后使用相同的算法对其进行哈希处理,并将结果值与数据库中的值进行比较 - 如果匹配,则知道用户再次输入了相同的字符串,但您仍然不会不知道,或者需要知道,它是什么。这比基于encyrption的解决方案更安全,如果您知道密钥,您可以随时恢复明文,而密钥必须由服务器知道,才能验证密码输入。

在.NET中对字符串进行散列的一个简单方法是使用System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(),尽管名称很长,但它是为使用ASP.NET Forms身份验证的用户提供的简单函数,但在别处也很有用。您可以指定MD5或SHA1作为散列算法(或者其他散列算法,如果未来框架版本支持的话)。我推荐SHA1,因为MD5已知有缺陷,但是随后SHA1可能也会有。

但是 - 这个方案存在缺陷。如果多个用户选择相同的密码,他们将具有相同的散列。如果黑客访问您的数据,他们可以运行暴力破解常见字符串并将这些字符与您存储的数据进行比较。如果他们遇到问题,他们会使用该密码破解所有帐户。由于用户倾向于选择蹩脚的密码,并且不愿意选择他们不记得的安全密码,这使得基于简单密码哈希的系统变得脆弱。

你应该做的是散列。这只是意味着将原始数据 - 密码 - 与一串随机字符串相加。这种盐需要尽可能的随机,并且至少要有几个字符(我推荐至少5个字符),最好是随机长度。将salt(未混淆)存储在数据库中的哈希盐+密码组合旁边的列中。当用户返回时,以相同的方式在输入前缀或后缀盐,然后像之前一样进行哈希比较。

这会降低强力攻击的有效性,因为即使用户使用相同的密码,每个用户也应该拥有不同的哈希值。您可以安全地将salt存储在数据库中,因为当您知道某些字符串时,如果密码本身比盐长且足够长而且强大到需要很长时间才能通过暴力破解(至少6个字符,至少有一个病例更改,并且有数字或非字母数字,我会说)。

如果有人在无限时间内无限制地访问您的数据,他们最终会破解哈希密码。但最终可能会持续数月或数年。如果您知道自己已经被入侵,那么在出现问题之前,可以让每个人的密码更改得当。

+0

+1感谢伟大的信息。我会尽快更新我的问题。我在想更多关于加密/散列应该如何与NHibernate和CAR协同工作。但是其他人应该根据哈希和安全性的解释进行投票。 – BuddyJoe 2009-01-27 15:42:58

我建议不要使用UserType进行单向散列,除非您有一个计划,以防止在后续调用NullSafeSet()时不断重新哈希散列化密码。

相反,我会建议您在密码属性上使用后台字段,在设置器中应用哈希方法并设置映射以使用字段访问。

对不起,也许它已不再适合你,但我希望可以帮助别人。

使用uNhAddins是我找到的最简单的方法,您只需关心HBM即可。

检查这个hbm example

希望能够帮助