2013-03-28 36 views
6

Tôi đang viết lại một ứng dụng Django trong Ruby on Rails và muốn giữ lại mật khẩu cũ cho người dùng.Xác minh mật khẩu Django trong Ruby on Rails cung cấp mật khẩu không khớp

Django sử dụng PBKDF2SHA1 làm cơ chế mã hóa. Vì vậy, một mật khẩu được mã hóa tôi có là

pbkdf2_sha256$10000$YsnGfP4rZ1IZ$Tpf4922MoNEjuJQA9EG2Elptyt3dMAyzBPUgmunFOW4= 

mật khẩu ban đầu này được 2bulls

Trong Ruby, tôi sử dụng PBKDF256 đá quý và base64 cho việc kiểm tra.

Base64.encode64 PBKDF256.dk("2bulls", "YsnGfP4rZ1IZ", 10000, 32) 

Tôi hy vọng

Tpf4922MoNEjuJQA9EG2Elptyt3dMAyzBPUgmunFOW4= 

Tuy nhiên, tôi đã

YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU= 

Bất kỳ ý tưởng?

CẬP NHẬT

Tìm mã trong nguồn django nếu nó có ý nghĩa hơn với bạn.

class PBKDF2PasswordHasher(BasePasswordHasher): 
    """ 
    Secure password hashing using the PBKDF2 algorithm (recommended) 

    Configured to use PBKDF2 + HMAC + SHA256 with 10000 iterations. 
    The result is a 64 byte binary string. Iterations may be changed 
    safely but you must rename the algorithm if you change SHA256. 
    """ 
    algorithm = "pbkdf2_sha256" 
    iterations = 10000 
    digest = hashlib.sha256 

    def encode(self, password, salt, iterations=None): 
     assert password 
     assert salt and '$' not in salt 
     if not iterations: 
      iterations = self.iterations 
     hash = pbkdf2(password, salt, iterations, digest=self.digest) 
     hash = base64.b64encode(hash).decode('ascii').strip() 
     return "%s$%d$%s$%s" % (self.algorithm, iterations, salt, hash) 

    def verify(self, password, encoded): 
     algorithm, iterations, salt, hash = encoded.split('$', 3) 
     assert algorithm == self.algorithm 
     encoded_2 = self.encode(password, salt, int(iterations)) 
     return constant_time_compare(encoded, encoded_2) 

    def safe_summary(self, encoded): 
     algorithm, iterations, salt, hash = encoded.split('$', 3) 
     assert algorithm == self.algorithm 
     return SortedDict([ 
      (_('algorithm'), algorithm), 
      (_('iterations'), iterations), 
      (_('salt'), mask_hash(salt)), 
      (_('hash'), mask_hash(hash)), 
     ]) 

KẾT LUẬN:

Nó chỉ ra rằng chỉ có tài khoản với 2bulls là mật khẩu có vấn đề này. Các tài khoản khác là tốt. Khi tôi biết lý do chính xác cho mật khẩu không phù hợp cho 2bull, tôi sẽ đăng ở đây.

+0

Tôi giả sử muối bạn đang sử dụng đến từ cài đặt Django, và số lặp lại từ đó cũng ('$ 10000 $' trong mật khẩu đầu tiên đó ?). Độ dài phù hợp. Bất kỳ cơ hội nào là vấn đề với mã hóa Base64? – pjmorse

+0

có. đối số thứ hai là muối. đối số thứ ba là số lần lặp lại, đối số cuối cùng là độ dài khóa. Tôi đang đào sâu vào mã nguồn django để điều tra bây giờ. – benzhang

+0

Ah, thú vị. Tôi thấy bây giờ, nơi bạn bắt nguồn tất cả các đối số. Vì vậy, đầu tiên nó được một sha256 tiêu hóa, sau đó chạy nó thông qua pbkdf2, sau đó mã hóa base64. Đó là những gì đá quý Ruby đang làm? (Tôi cũng sẽ xem xét.) Ngoài ra, chúng ta có thể xác minh rằng băm sha256 của Python tạo ra cùng một kết quả như Ruby trên cùng một chuỗi không? Điều đó có vẻ giống như một mẫu số ít phổ biến nhất. – pjmorse

Trả lời

6

Nếu bạn băm rằng mật khẩu 2bulls sử dụng đoạn mã sau (cùng logic mà Django sử dụng để băm mật khẩu) đây là những gì bạn nhận được (chạy này trên vỏ của Django):

>>> import base64, hashlib 
>>> hash = pbkdf2("2bulls","YsnGfP4rZ1IZ", 10000, 32, hashlib.sha256) 
>>> hash.encode('base64').strip() 
'YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU=' 

Chú ý làm thế nào tôi đang sử dụng các thông số tương tự mà bạn đang sử dụng trong Ruby:

password = "2bulls" 
salt = "YsnGfP4rZ1IZ" 
iterations = 10000 
dklen = 32 
digest = hashlib.sha256 

Bạn có chắc chắn băm dự kiến ​​tương ứng với mật khẩu 2bulls?

0

Tôi vừa mới phát hành một viên ngọc cho mục đích này. Tôi cũng nhận được kết quả tương tự như @Daniel Aronne:

require 'pbkdf2_password_hasher' 

puts Pbkdf2PasswordHasher::hash_password('2bulls','YsnGfP4rZ1IZ',10000,32) 
#=> "YEfK6oUGFHdaKZMDXC0Dz8TpwsJlKfqC5vjCxjo+ldU=" 
Các vấn đề liên quan