代码之家  ›  专栏  ›  技术社区  ›  PreciousBodilyFluids

Bcrypt说,长的,相似的密码是等价的-对我,宝石,还是密码学领域的问题?

  •  4
  • PreciousBodilyFluids  · 技术社区  · 14 年前

    我一直在用Bcrypt做实验,发现了以下几点。如果重要的话,我运行的是Ruby1.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
    

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

    然后,我试着缩短每个长字符串,看看bcrypt从何处开始能够将它们分开,我发现如果我将每个长字符串缩短到100个字符左右,最终的尝试(“passwor”)也将开始返回true。所以现在我不知道该怎么想。

    对此有什么解释?

    2 回复  |  直到 14 年前
        1
  •  7
  •   HostileFork says dont trust SE    14 年前

    这个 好消息 也就是说,加密的数学基础还没有被溶解。:)

    这个 坏消息 是不是有一个 8-bit key length limit in bcrypt.c 这是无声的失败:

    uint8_t key_len, salt_len, logr, minor;
    

    然后:

    key_len = strlen(key) + (minor >= 'a' ? 1 : 0);
    

    你输入的加密字符数是263个,但最后却认为只有8个。所以你只在字符串的第一部分进行比较。

    但是,当我减少 long_string 如果你真的在255分的范围内遇到了一个问题,那可能与其他问题有关。

        2
  •  5
  •   James    14 年前

    河豚的p数组是18个4字节的整数。bcrypt xor将该数组的密码加上NULL,然后重复该过程,直到结束。假设我的密码是12345,它将以12345(空)12345(空)12345(空)12345(空)12345(空)等与p数组异或…

    Eksblowfish的完整描述是 here . 简短的版本是,bcrypt只使用前72个字节。