BCrypt说长,类似的密码是等价的 - 我,宝石或密码学领域的问题?

Pre*_*ids 4 ruby encryption passwords integer-overflow bcrypt

我一直在试验BCrypt,并发现了以下内容.如果重要的话,我正在运行ruby 1.9.2dev(2010-04-30 trunk 27557)[i686-linux]

require 'bcrypt' # bcrypt-ruby gem, version 2.1.2

@long_string_1 = 'f287ed6548e91475d06688b481ae8612fa060b2d402fdde8f79b7d0181d6a27d8feede46b833ecd9633b10824259ebac13b077efb7c24563fce0000670834215'
@long_string_2 = 'f6ebeea9b99bcae4340670360674482773a12fd5ef5e94c7db0a42800813d2587063b70660294736fded10217d80ce7d3b27c568a1237e2ca1fecbf40be5eab8'

def salted(string)
  @long_string_1 + string + @long_string_2
end

encrypted_password = BCrypt::Password.create(salted('password'), :cost => 10)
puts encrypted_password #=> $2a$10$kNMF/ku6VEAfLFEZKJ.ZC.zcMYUzvOQ6Dzi6ZX1UIVPUh5zr53yEu

password = BCrypt::Password.new(encrypted_password)

puts password.is_password?(salted('password')) #=> true
puts password.is_password?(salted('passward')) #=> true
puts password.is_password?(salted('75747373')) #=> true
puts password.is_password?(salted('passwor')) #=> false
Run Code Online (Sandbox Code Playgroud)

起初我认为一旦密码达到一定长度,所有散列中的差异就会丢失,只有当它们非常不相似(即不同的长度)时才会被识别为不同.从我所知的散列函数来看,这对我来说似乎不太合理,但我没有看到更好的解释.

然后,我尝试缩短每个long_strings以查看BCrypt开始能够区分它们的位置,并且我发现如果我将每个长字符串缩短到100个字符左右,最后的尝试('passwor')将开始也是如此.所以现在我不知道该怎么想.

对此有何解释?

Hos*_*ork 7

利好消息是,加密的数学基础还没有被解散.:)

坏消息是,有一个在bcrypt.c 8位密钥长度的限制这是默默地失败:

uint8_t key_len, salt_len, logr, minor;
Run Code Online (Sandbox Code Playgroud)

然后呢:

key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
Run Code Online (Sandbox Code Playgroud)

你传递的加密内容是263个字符,但它最终认为它只有8个.所以你只能在字符串的第一部分进行比较.

但是,当我削减long_strings 的长度时,它对我来说很好,所以如果你确实在255以下的范围内得到了一个可能与其他东西有关的问题.

  • 我想这个修复可能是让bcrypt()在有一个太长的键时返回NULL.此外,由于密码结构中已经存在盐,而bcrypt表面上是为了解决您所关注的安全问题,所以我不会在此处烦恼. (2认同)

Jam*_*mes 5

Blowfish的P阵列长18个4字节整数.BCrypt通过密码+ null对此数组进行XOR,然后重复该过程直到它结束.假设我的密码是12345,它会将P阵列异或12345(null)12345(null)12345(null)等...

这里有EksBlowfish的完整描述.短版本是,BCrypt只使用前72个字节.