it-swarm-vi.com

Số vòng được đề xuất cho bcrypt

Ngày nay (tháng 7 năm 2012) số vòng bcrypt được đề xuất để băm mật khẩu cho một trang web trung bình (chỉ lưu trữ tên, địa chỉ email và địa chỉ nhà, nhưng không có thẻ tín dụng hoặc thông tin y tế)?

Nói cách khác, khả năng hiện tại của cộng đồng bẻ khóa mật khẩu bcrypt là gì? Một số thư viện bcrypt sử dụng 12 vòng (2 ^ 12 lần lặp) làm cài đặt mặc định. Đó có phải là công việc được đề nghị? 6 vòng sẽ không đủ mạnh (điều này có thể là giới hạn cho băm mật mã phía máy khách trong Javascript, xem thêm Thử thách đầy thách thức: băm mật khẩu phía máy khách và xác minh mật khẩu phía máy chủ )?

Tôi đã đọc câu trả lời https://security.stackexchange.com/a/3993/11197 trong đó đưa ra một cuộc thảo luận chuyên sâu về cách cân bằng các yếu tố khác nhau (mặc dù cho PBKDF2-SHA256). Tuy nhiên, tôi đang tìm kiếm một con số thực tế. Một quy tắc của ngón tay cái.

94
Jason Smith

Tôi nghĩ rằng câu trả lời cho tất cả các câu hỏi của bạn đã có trong câu trả lời của Thomas Porn . Bạn đã liên kết với nó, vì vậy bạn có thể biết về nó, nhưng tôi khuyên bạn nên đọc lại.

Các nguyên tắc cơ bản là: không chọn một số vòng; thay vào đó, hãy chọn số lượng thời gian xác minh mật khẩu sẽ có trên máy chủ của bạn, sau đó tính số vòng dựa trên số đó. Bạn muốn xác minh mất bao lâu bạn có thể đứng.

Đối với một số ví dụ về các con số cụ thể, xem câu trả lời của Thomas Pornin. Ông đề xuất một mục tiêu hợp lý sẽ là xác minh/băm mật khẩu để mất 241 mili giây cho mỗi mật khẩu. (Lưu ý: Thomas ban đầu đã viết "8 mili giây", điều này là sai - đây là con số cho sự kiên nhẫn của một ngày thay vì một tháng.) Điều đó vẫn cho phép máy chủ của bạn xác minh 4 mật khẩu mỗi giây (nhiều hơn nếu bạn có thể làm điều đó song song). Thomas ước tính rằng, nếu đây là mục tiêu của bạn, khoảng 20.000 vòng là ở đúng sân bóng.

Tuy nhiên, số vòng tối ưu sẽ thay đổi với bộ xử lý của bạn. Lý tưởng nhất là bạn sẽ đánh giá thời gian cần thiết cho bộ xử lý của mình và chọn số phù hợp. Điều này không mất nhiều thời gian; Vì vậy, để có kết quả tốt nhất, chỉ cần viết kịch bản và tìm ra số vòng cần thiết để đảm bảo việc băm mật khẩu mất khoảng 240 mili giây trên máy chủ của bạn (hoặc lâu hơn, nếu bạn có thể chịu đựng được).

41
D.W.

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

Họ cũng lưu ý:

Tất nhiên, mọi lúc mọi người lựa chọn nên được đánh giá lại

Chi phí bcrypt của 6 có nghĩa là 64 vòng (2 6  = 64).

Nếu chúng tôi sử dụng giá trị ban đầu "người dùng bình thường", chúng tôi muốn thử điều chỉnh lạm phát sức mạnh tính toán ( giả sử trung bình nó tăng gấp đôi cứ sau 18 tháng ).

R = R × 2(tháng/18)
[.__.] R = 64 × 2(tháng/18)

Hôm nay (ngày 9 tháng 3 năm 2015) là 171 tháng kể từ ngày 31/12/1999 (hoặc sử dụng 1/1/2000 để đơn giản), số vòng nên tăng gấp đôi một chút trong 9 lần:

R = 64 × 2(171/18)
[.__.] R = 64 × 29,5
[.__.] R = 64 × 724.1
[.__.] R = 46.341,0

Cuối cùng, chúng tôi muốn chuyển đổi lại thành a hệ số chi phí

chi phí = ln (R)/ln (2)
[.__.] chi phí = ln (46,341.0)/ln (2)
[.__.] chi phí = 15,5

Tính thực tiễn của hệ số chi phí là 15 phụ thuộc vào khả năng tính toán của máy chủ của bạn. Ví dụ: máy tính để bàn của tôi là CPU Intel Core i7-2700K @ 3.50 GHz. Ban đầu tôi đã điểm chuẩn triển khai BCrypt vào ngày 1/23/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ưng đó là năm 2014

Những thời gian đó ban đầu được tính vào đầu năm 2014. Chỉ nên sử dụng 156 tháng (chứ không phải 171) trong tính toán của tôi:

R = 64 × 2(156/18)
[.__.] R = 64 × 28,66
[.__.] R = 64 × 406.8
[.__.] R = 26,035,2

chi phí = ln (R)/ln (2)
[.__.] chi phí = ln (26,035,2)/ln (2)
[.__.] chi phí = 14,7

Nhưng i7-2700K đã bị ngừng sản xuất

I7-2700K đã bị ngừng sản xuất (Q1 2013) khi tôi chạy điểm chuẩn của mình. Nó đã được phát hành, và là công nghệ tiên tiến, vào quý 4 năm 2011. Nếu tôi chạy các số cho Q4 2011:

R = 64 × 2(129/18)
[.__.] R = 64 × 27,16
[.__.] R = 64 × 143,7
[.__.] R = 9.196.8

chi phí = ln (R)/ln (2)
[.__.] chi phí = ln (9.196.8)/ln (2)
[.__.] chi phí = 13,2

Chi phí là 13, trên máy tính để bàn của tôi, gần 2 giây hơn một giây.

Bao lâu bạn có thể chịu đựng được?

Điều đó mang đến cho bạn một hương vị của loại chậm trễ mà những người thực hiện ban đầu đang xem xét khi họ viết nó: ~ 0,5-1 giây.

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 mà tôi thấy đã sử dụng 10 là chi phí mặc định. Và triển khai của tôi đã sử dụng nó. Tôi tin rằng đã đến lúc tôi phải tăng chi phí mặc định lên 12.

Chứng minh trong tương lai

Tôi cũng có thể thay đổi hàm băm:

hash = HashPassword("correct battery horse stapler");

tức là nơi bạn dựa vào chi phí mặc định, thay vào đó sử dụng chi phí trượt tự động. Bằng cách này, chi phí sẽ tự tăng theo thời gian. Thay đổi:

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

đến 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;
}

Chỉnh sửa 3/12/2015 : Cập nhật số tốc độ. Trình biên dịch Delphi XE6 32 bit (c.2013) tạo mã có độ lớn nhanh hơn Delphi 5 (c.1999) cho cùng một bộ xử lý. Trình biên dịch Delphi XE6 64 bit tạo mã chậm hơn 20% so với trình biên dịch 32 bit.

61
Ian Boyd

Dẫn xuất khóa mạnh hơn thông qua các chức năng cứng bộ nhớ tuần tự là một bài viết rất hay về chủ đề kéo dài khóa. Trên trang 14, nó so sánh các thuật toán băm khác nhau với chi phí bao nhiêu để phá vỡ hàm băm, đây là một cách suy nghĩ hữu ích về những điều này. (Trên một lưu ý phụ ChromeOS sử dụng Scrypt nếu TPM không khả dụng.)

Ý tưởng là bạn muốn các băm mật khẩu này không bị phá vỡ càng lâu càng tốt. Với định luật Moore, đây là mục tiêu di chuyển nhanh theo cấp số nhân. Scrypt sử dụng lượng bộ nhớ và cpu thay đổi, biến này có thể trở nên nặng hơn như là một hàm của thời gian. Trong đó mỗi khi khách hàng đăng nhập, bạn có thể cập nhật mật khẩu băm để an toàn hơn. Trong trường hợp PBKDF2, nó có thể trông giống như rounds=2^(current_year-2000) hoặc đại loại như thế.

Điều quan trọng cần lưu ý là bạn không thể giảm tải quá trình xử lý này lên máy khách và mong muốn giao thức của bạn được an toàn. Tất cả các giao thức xác thực băm phía máy khách mà tôi biết yêu cầu máy chủ thực hiện một phép tính giống hệt nhau để xác minh thông tin xác thực (NTLM, NTLMv2, SRP, WPA-PSK ...).

3
rook