如何使用“Bcrypt”宝石比较解密密码和加密密码?

6

我正在尝试为帖子的评论使用简单认证功能。

用户输入评论时需要提供即时ID和密码

并且我使用 'bcrypt' gem 将密码存储在数据库中。

评论控制器 comments_controller.rb 如下:

@comment = Comment.new(comment_params)
bcrypted_pwd = BCrypt::Password.create(@comment.user_pwd)
@comment.user_pwd = bcrypted_pwd

我使用data-confirm-modal gem来确认用户在删除评论时的数据。

在这一部分中,我需要解密用户输入的密码以与数据库中的加密密码进行比较。

如何解密密码?是否有更好的方法可以实现?


你使用了“devise”宝石吗? - Vishal
3
不应解密密码。您应该加密新密码,然后与数据库中的加密密码进行比较。 - Nermin
@Nermin 不需要加密新密码。我们可以在不加密的情况下检查两个密码。 - Vishal
2
@Nermin:不,不,不,不,千万不要加密密码。绝对不要。永远不要。你应该使用专门的密码哈希算法进行散列(Hash)和加盐(Salt)。如果你将其加密,存在密钥泄露导致密码被解密的风险。 - Jörg W Mittag
1
@DongkunLee 我已经发布了答案,请查收。 - Vishal
显示剩余5条评论
2个回答

18
ency_pass = BCrypt::Password.create("testing")
new_pass = "testing"

让我们看一下如何比较来自数据库和用户输入(例如表单或类似物品)的两个bcrypt哈希值。

BCrypt::Password.new(ency_pass) == new_pass
# true
BCrypt::Password.new(ency_pass) == "testing2"
#false
左侧的部分 (BCrypt::Password.new) 是一个 BCrypt 对象,它将数据库中存储的哈希值作为参数。右侧的部分 (new_pass) 则是用户尝试登录的明文密码。
BCrypt 使用称为“盐”的随机值来提高对预计算哈希的安全性。盐值存储在哈希本身中。BCrypt 定义了自己的 == 方法,该方法知道如何提取“盐”值,以便在比较密码时考虑到它。
BCrypt#== 从存储的哈希中获取“盐”值,然后使用此盐对明文密码(用户输入)进行哈希,以便如果密码有效,则两个哈希将相同。
如果您查看源代码,它看起来会像这样:
def ==(secret)
 super(
  BCrypt::Engine.hash_secret(secret, @salt)
 )
end

记住,super会在父类上调用同名方法(在这种情况下是==)。BCrypt::Password的父类是String。


非常感谢您的帖子!!我认为我可以解决它。 - PrepareFor
@DongkunLee 请接受这个答案。这样其他用户就会更容易了解。 - Vishal
很棒,你花时间解释了BCrypt::Password类的工作原理。将其作为String的子类并重写==非常方便,但也掩盖了其中的过程。在IRB(或rails console)中,它看起来像是在比较两个字符串。 - Stefan

-1
如何解密密码?有没有好的方法可以做到这一点?
你不能。你只能解密已经加密的东西。Bcrypt不是加密算法,而是哈希算法。你无法反向哈希。这是可以证明的不可能的事情。(而且这个证明甚至不难,一个高中生就可以理解。)

不确定为什么会有负评。可能是因为“高中生”的评论 :) - Sergio Tulentsev
1
显然,OP使用了错误的术语(混淆了“加密”和“哈希”,甚至可能不知道区别),并且从错误的角度来解决问题。但仅仅声明“你不能这样做”并没有多大帮助(因此被踩了?) - Stefan
@SergioTulentsev:如果你有三只袜子和两个抽屉,那么无论如何在两个抽屉中分配这三只袜子都无关紧要,总会有至少一个抽屉里面有至少两只袜子。因此,当我让你从抽屉里面取出一只袜子时,在某些情况下这显然不可能工作,因为有时候一个抽屉里会有两只袜子而你不知道该拿哪只给我。这就是证明OP所要求的是不可能的,而且我真的相信一名高中生能够理解它。这并不夸张。没有必要害怕“证明”。 - Jörg W Mittag
1
@Stefan:如果有人试图做一些在数学上被证明是不可能的事情,那么“你不能这样做,因为在数学上已经被证明是不可能的”就是一个完全有效的回答。 - Jörg W Mittag

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接