Hệ số công việc bcrypt tối ưu


80

Yếu tố công việc bcrypt lý tưởng để băm mật khẩu là gì.

Nếu tôi sử dụng hệ số 10, sẽ mất khoảng 0,1 giây để băm một mật khẩu trên máy tính xách tay của tôi. Nếu chúng ta kết thúc với một trang web rất bận rộn, điều đó sẽ trở thành một công việc tốt chỉ cần kiểm tra mật khẩu của mọi người.

Có lẽ sẽ tốt hơn nếu sử dụng hệ số công việc là 7, giảm tổng công việc băm mật khẩu xuống còn khoảng 0,01 giây cho mỗi lần đăng nhập máy tính xách tay?

Làm thế nào để bạn quyết định sự cân bằng giữa an toàn vũ phu và chi phí hoạt động?


7
Chi phí ngăn cản các cuộc tấn công ngoại tuyến. Khi "trực tuyến", bạn có thể sử dụng độ trễ tối thiểu giữa các lần thử (ví dụ 5 giây) để ngăn chặn tấn công từ chối dịch vụ.
Ian Boyd

3
Trùng lặp về thông tin Bảo mật: Số vòng được đề xuất cho bcrypt
Christian Strempfer

1
Đối với bất kỳ ai quan tâm, tôi vừa viết một công cụ Java CLI nhỏ để kiểm tra hiệu suất bcrypt trên máy chủ (điều này rõ ràng là quan trọng để cân bằng bảo mật, tải máy chủ và thời gian phản hồi): github.com/cdraeger/hash-performance
Blacklight

Câu trả lời:


103

Hãy nhớ rằng giá trị được lưu trữ trong các mật khẩu: $2a$(2 chars work)$(22 chars salt)(31 chars hash). Nó không phải là một giá trị cố định.

Nếu bạn thấy tải quá cao, chỉ cần thực hiện để lần sau khi họ đăng nhập, bạn chuyển sang một thứ gì đó nhanh hơn để tính toán. Tương tự như vậy, khi thời gian trôi qua và bạn nhận được các máy chủ tốt hơn, nếu tải không phải là vấn đề, bạn có thể nâng cấp sức mạnh băm của họ khi họ đăng nhập.

Bí quyết là giữ cho nó mất khoảng thời gian tương đương mãi mãi trong tương lai cùng với Định luật Moore. Số là log2, vì vậy mỗi khi máy tính tăng gấp đôi, hãy thêm 1 vào số mặc định.

Quyết định xem bạn muốn mất bao lâu để bắt buộc mật khẩu của người dùng. Ví dụ: đối với một số từ điển thông dụng, việc tạo tài khoản của bạn có thể đã cảnh báo họ mật khẩu của họ yếu. Nếu đó là một trong số 1000 từ thông dụng, và kẻ tấn công phải mất 0,1 giây để kiểm tra mỗi từ, điều đó sẽ mua chúng 100s (tốt, một số từ phổ biến hơn ...). Nếu người dùng chọn 'từ thông dụng trong từ điển' + 2 số, thì đó là hơn hai giờ. Nếu cơ sở dữ liệu mật khẩu của bạn bị xâm phạm và kẻ tấn công chỉ có thể lấy được vài trăm mật khẩu mỗi ngày, bạn đã mua hầu hết người dùng của mình hàng giờ hoặc hàng ngày để thay đổi mật khẩu của họ một cách an toàn. Đó là một vấn đề của họ thời gian.

http://www.postgresql.org/docs/8.3/static/pgcrypto.html có một số lần bẻ khóa mật khẩu để bạn xem xét. Tất nhiên, mật khẩu họ liệt kê ở đó là các chữ cái ngẫu nhiên. Từ điển ... Thực tế mà nói, bạn không thể lưu anh chàng có mật khẩu là 12345.


8
Đây thực sự là một câu trả lời xuất sắc. Tôi thậm chí đã không xem xét ý tưởng đăng nhập lại tiền mã hóa. Cảm ơn bạn rất nhiều!
Chris

1
Việc giải mã lại sẽ hoạt động như thế nào? Bạn sẽ phải lưu trữ chi phí công việc bcrypt cũ ở đâu đó để bạn có thể sử dụng nó để đăng nhập chúng và sau khi xác thực mật khẩu của chúng, bạn sẽ cập nhật hàm băm và chi phí trong cơ sở dữ liệu?
Jerry Saravia

6
@JerrySaravia Cái hay của bcrypt là chi phí được lưu trữ trong chính hàm băm - vì vậy bạn không cần phải lưu trữ thêm bất cứ thứ gì . Đơn giản chỉ cần xác thực với hàm băm hiện tại, sau đó ngay lập tức tạo lại hàm băm với chi phí khác. Đơn giản!
Đánh dấu Locker

@MarkLocker, Cảm ơn Mark! Đó là một hầm mộ B [đẹp]! Nhưng nghiêm túc mà nói, điều đó làm cho mọi thứ dễ dàng hơn nhiều và là một điều tuyệt vời.
Jerry Saravia

Được rồi vì tôi không được phép chỉnh sửa vì đó là "nỗ lực trả lời không chính xác" (các bạn thậm chí có đọc các chỉnh sửa của tôi không?), Hãy cho phép tôi nhận xét thông tin thay thế. Giá trị Ví dụ: $2y$08$fJS4yx0i8kiOzIBIamZ51OWTMrzyE/4je34Oxhw.5xxp3Es7Ke32W. Lý do tôi cố gắng chỉnh sửa: Tôi không rõ liệu "2 ký tự hoạt động" là một chữ số hay hex hay gì đó, phải kiểm tra. Đây là kết quả thử nghiệm cho những người khác nên bạn không cần phải tự mình thử.
Luc

3

Phiên bản ngắn

Số lần lặp cung cấp ít nhất 250 mili giây để tính toán

Phiên bản dài

Khi BCrypt được xuất bản lần đầu tiên vào năm 1999, họ đã liệt kê các yếu tố chi phí mặc định của việc triển khai:

  • người dùng bình thường: 6
  • siêu người dùng: 8

Giá bcrypt là 6 có nghĩa là 64 vòng (2 6 = 64).

Họ cũng lưu ý:

Tất nhiên, bất cứ giá nào mọi người chọn cũng nên được đánh giá lại theo thời gian

  • Vào thời điểm triển khai vào năm 1976, crypt có thể băm ít hơn 4 mật khẩu mỗi giây. (250 mili giây cho mỗi mật khẩu)
  • Năm 1977, trên VAX-11/780, crypt (MD5) có thể được đánh giá khoảng 3,6 lần mỗi giây. (277 ms cho mỗi mật khẩu)

Điều đó cung cấp cho bạn hương vị của loại sự chậm trễ mà những người triển khai ban đầu đã xem xét khi họ viết nó:

  • ~ 250 ms cho người dùng bình thường
  • ~ 1 giây cho người dùng siêu.

Nhưng, tất nhiên, bạn có thể đứng càng lâu thì càng tốt. Mọi triển khai BCrypt tôi đã thấy được sử dụng 10làm chi phí mặc định. Và triển khai của tôi đã sử dụng điều đó. Tôi tin rằng đã đến lúc tôi tăng chi phí mặc định lên 12.

Chúng tôi đã quyết định muốn nhắm mục tiêu không dưới 250 mili giây mỗi băm.

Máy tính để bàn của tôi là CPU Intel Core i7-2700K @ 3,50 GHz. Ban đầu, tôi đã chuẩn hóa việc triển khai BCrypt vào ngày 23 tháng 2 năm 2014:

1/23/2014  Intel Core i7-2700K CPU @ 3.50 GHz

| Cost | Iterations        |    Duration |
|------|-------------------|-------------|
|  8   |    256 iterations |     38.2 ms | <-- minimum allowed by BCrypt
|  9   |    512 iterations |     74.8 ms |
| 10   |  1,024 iterations |    152.4 ms | <-- current default (BCRYPT_COST=10)
| 11   |  2,048 iterations |    296.6 ms |
| 12   |  4,096 iterations |    594.3 ms |
| 13   |  8,192 iterations |  1,169.5 ms |
| 14   | 16,384 iterations |  2,338.8 ms |
| 15   | 32,768 iterations |  4,656.0 ms |
| 16   | 65,536 iterations |  9,302.2 ms |

nhập mô tả hình ảnh ở đây

Chứng minh trong tương lai

Thay vì có một hằng số cố định, nó phải là một mức tối thiểu cố định .

Thay vì có hàm băm mật khẩu của bạn, hãy:

String HashPassword(String password)
{
   return BCrypt.HashPassword(password, BCRYPT_DEFAULT_COST);
}

nó phải là một cái gì đó như:

String HashPassword(String password)
{  
   /*
     Rather than using a fixed default cost, run a micro-benchmark
     to figure out how fast the CPU is.
     Use that to make sure that it takes **at least** 250ms to calculate
     the hash
   */
   Int32 costFactor = this.CalculateIdealCost();
   //Never use a cost lower than the default hard-coded cost
   if (costFactor < BCRYPT_DEFAULT_COST) 
      costFactor = BCRYPT_DEFAULT_COST;

   return BCrypt.HashPassword(password, costFactor);
}

Int32 CalculateIdealCost()
{
    //Benchmark using a cost of 5 (the second-lowest allowed)
    Int32 cost = 5;

    var sw = new Stopwatch();
    sw.Start();
    this.HashPassword("microbenchmark", cost);
    sw.Stop();

    Double durationMS = sw.Elapsed.TotalMilliseconds;

    //Increasing cost by 1 would double the run time.
    //Keep increasing cost until the estimated duration is over 250 ms
    while (durationMS < 250)
    {
       cost += 1;
       durationMS *= 2;
    }

    return cost;
}

Và lý tưởng nhất, đây sẽ là một phần của thư viện BCrypt của mọi người, vì vậy thay vì dựa vào những người sử dụng thư viện để tăng chi phí theo định kỳ, chi phí tự tăng theo định kỳ.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.