Ruby-BCrypt:指定salt

时间:2013-10-24 23:00:36

标签: ruby-on-rails ruby bcrypt bcrypt-ruby

使用ruby-bcrypt加密字符串时是否可以指定使用哪种盐?

我知道它不是很安全,但我只将它用于不高的安全数据: 我有一个平台,当用户删除他的帐户时,我仍然想知道此用户之前是否已使用此电子邮件注册(由于注册时的免费信用)。

所以我想我会用Bcrypt加密电子邮件(删除之前),之后我可以查询当用户想要再次注册这个电子邮件地址时是否存在这个哈希?

但现在我意识到bcrypt总是采用新盐...我可以用某种方式指定盐吗?

谢谢,

声明/注意:

一般来说,你不应该直接指定盐 - 它的不确定!!!

3 个答案:

答案 0 :(得分:7)

是的,你可以:

BCrypt::Engine.hash_secret( 'foo@example.com', "$2a$10$ThisIsTheSalt22CharsX." )

前7个字符在技术上不是盐,它们识别bcrypt算法,并将迭代次数设置为2 ** 10 == 1024.为简单起见,Ruby的bcrypt模块将第一个字符视为盐的一部分,所以你也需要。你应该使用

BCrypt::Engine.generate_salt

创建共享盐,因为这不依赖于你提出“随机”的东西。

为了稍微提高安全性,您可以将盐与可搜索的哈希分开,并将其视为应用程序中的任何其他秘密数据。例如,将它设置为配置项,并且只存储bcrypt的哈希部分以进行搜索(无论如何,第一部分都是冗余数据并且会降低搜索的性能,尽管这种影响可能非常小):

email = 'foo@example.com'
full_hash = BCrypt::Engine.hash_secret( email, settings.email_search_salt )
searchable_hash = full_hash[29,31]
# Either store or search . . .

答案 1 :(得分:4)

可以使用BCrypt::Password.create,将电子邮件传递给它,以生成这些哈希值和唯一的盐。

2.0.0-p195 :003 > hashed_email = BCrypt::Password.create 'joe@test.com'
 => "$2a$10$vX2tl3omW9h4k66XC7/BwOFH0n7EqtH4PJATPa7YVSeJh7TEpt/bK" 
2.0.0-p195 :004 > hashed_email = BCrypt::Password.create 'joe@test.com'
 => "$2a$10$RdQIHtz.L5To1F1XRK//..h6nHYdQ3uJ2PTgB58e3xufoqgZGqbO6" 
2.0.0-p195 :005 > hashed_email = BCrypt::Password.create 'joe@test.com'
 => "$2a$10$bTFVXO/d0/sf6SxzCcRMU.zBPcR5yjI6ID6O9J2eXKbqim/jPM3PC" 
2.0.0-p195 :006 > hashed_email = BCrypt::Password.create 'joe@test.com'
 => "$2a$10$gbXU4UEiHTC0HCnD672Dm.TeBhZeCa6sBiX8Pk50KSXcprDJnEYA." 

现在你不必担心使用固定的盐,因为BCrypt已经为你存储了哈希值。

但是我猜你已经确定这意味着稍后会有一个与比较相关的处理成本,因为你不能只做一个'SELECT用户WHERE email_hash = hash ” ...

如果你绝对想要使用固定盐,你可以。

salt = BCrypt::Engine.generate_salt
hash = BCrypt::Engine.hash_secret 'hello', salt

(只需将盐线存储在某个地方,稍后就可以使用了。)

答案 2 :(得分:0)

这是一个非常老的线程,但仍然...这是使用固定盐进行加密的其他选项:

如果安全性不是问题(仅仅是混淆):请使用md5

Digest::MD5.hexdigest 'some value'

优点:计算便宜(生成速度更快)

缺点:计算上便宜(黑客入侵速度更快)

如果安全性成问题,则可以使用共享机密(无哈希)对它进行加密。参见https://ruby-doc.org/stdlib-2.5.1/libdoc/openssl/rdoc/OpenSSL.html#module-OpenSSL-label-Encryption