2011-12-16 31 views
6

Có một ứng dụng được viết bằng PHP mà tôi đang chuyển đổi sang Ruby. Khi mã hóa mật khẩu, ứng dụng PHP sử dụng mã sau:Xác thực mật khẩu được mã hóa bằng PHP bằng Blowfish với Ruby

if($method == 2 && CRYPT_BLOWFISH) return crypt($pass, '$2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$'); 

Tôi giả định đây là việc sử dụng triển khai Blowfish. Các x ở đây là tất cả các ký tự a-zA-Z0-9.

Việc thực hiện Blowfish trong Ruby sử dụng cú pháp sau (lấy từ http://crypt.rubyforge.org/blowfish.html):

blowfish = Crypt::Blowfish.new("A key up to 56 bytes long") 
plainBlock = "ABCD1234" 
encryptedBlock = blowfish.encrypt_block(plainBlock) 

Tôi không có một chuỗi dài 56 hoặc ít byte và nó không phải là rõ ràng những gì mà nên từ phiên bản PHP . Vậy làm thế nào tôi có thể viết một hàm Ruby sẽ mã hóa mật khẩu để đưa ra kết quả tương tự như PHP?

Trả lời

4

Mã PHP băm $pass với muối $2a$07$xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxxxx$ nếu CRYPT_BLOWFISH được đặt (CRYPT_BLOWFISH == 1). Muối phải tuân theo định dạng được chỉ ra trong tài liệu PHP ("$2a$", a two digit cost parameter, "$", and 22 digits from the alphabet "./0-9A-Za-z").

Tôi không chắc liệu bạn có thể làm điều đó với thư viện bạn đang giới thiệu hay không, nhưng bạn có thể sử dụng bcrypt-ruby để thay thế.

Đối với mã của bạn nó sẽ là một cái gì đó như thế này, tôi đang sử dụng cùng một dữ liệu từ ví dụ PHP (http://php.net/manual/en/function.crypt.php), tôi chỉ mất 29 ký tự đầu tiên của muối vì ngoài PHP mà bỏ qua nó:

require 'bcrypt-ruby' 
pass = "rasmuslerdorf" # Here you should put the $pass from your PHP code 
salt = '$2a$07$usesomesillystringfors' # Notice no $ at the end. Here goes your salt 
hashed_password = BCrypt::Engine.hash_secret(pass,salt) # => "$2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi" 

Điều này cho bạn kết quả tương tự như trên ví dụ PHP. Nếu muối của bạn quá dài mất 29 ký tự đầu tiên ($ 2a $ 07 $ cộng với 22 ký tự phụ tiếp theo).

Tôi đã thử nghiệm hành vi của PHP, nếu muối quá dài (vượt quá 29 ký tự trong tổng số) phần còn lại được bỏ qua, nếu muối là quá ngắn nó sẽ trở lại 0. Ví dụ trong PHP:

<?php 
    crypt('rasmuslerdorf', '$2a$07$usesomesillystringforsalt$') 
    // returns $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi 

    crypt('rasmuslerdorf', '$2a$07$usesomesillystringfors') 
    // returns $2a$07$usesomesillystringfore2uDLvp1Ii2e./U9C8sBjqp8I90dH6hi 

    crypt('rasmuslerdorf', '$2a$07$usesomesilly') 
    // returns 0 because the salt is not long enough 
?> 
+0

Điều này hoạt động hoàn hảo. Cảm ơn! –

Các vấn đề liên quan