लघु संस्करण
पुनरावृत्तियों की संख्या जो गणना करने के लिए कम से कम 250 एमएस देती है
दीर्घ संस्करण
जब BCrypt पहली बार प्रकाशित हुआ था, 1999 में, उन्होंने अपने कार्यान्वयन की डिफ़ॉल्ट लागत कारकों को सूचीबद्ध किया:
- सामान्य उपयोगकर्ता: 6
- सुपर उपयोगकर्ता: 8
6 की एक bcrypt लागत का मतलब 64 राउंड (2 6 = 64) है।
उन्होंने यह भी ध्यान दिया:
बेशक, जो भी लोग चुनते हैं, उन्हें समय-समय पर फिर से मूल्यांकन किया जाना चाहिए
- 1976 में तैनाती के समय, क्रिप्ट प्रति सेकंड 4 से कम पासवर्ड हैश कर सकता था। (250 एमएस प्रति पासवर्ड)
- 1977 में, VAX-11/780 पर, क्रिप्ट (MD5) का मूल्यांकन प्रति सेकंड 3.6 गुना किया जा सकता था। (277 एमएस प्रति पासवर्ड)
यह आपको उस तरह की देरी का स्वाद देता है जो मूल कार्यान्वयनकर्ताओं ने विचार किया था जब उन्होंने इसे लिखा था:
- ~ 250 एमएस सामान्य उपयोगकर्ताओं के लिए
- सुपर उपयोगकर्ताओं के लिए ~ 1 सेकंड।
लेकिन, निश्चित रूप से, आप जितने लंबे समय तक खड़े रह सकते हैं, बेहतर है। प्रत्येक BCrypt कार्यान्वयन मैंने 10
डिफ़ॉल्ट लागत के रूप में उपयोग किया है । और मेरे कार्यान्वयन ने इसका इस्तेमाल किया। मेरा मानना है कि मेरे लिए डिफ़ॉल्ट लागत को बढ़ाकर 12 करने का समय है।
हमने तय किया है कि हम प्रति हैश 250 ग्राम से कम का लक्ष्य नहीं रखना चाहते हैं।
मेरा डेस्कटॉप पीसी एक Intel Core i7-2700K CPU @ 3.50 GHz है। मैंने मूल रूप से 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 |
फ्यूचर प्रूफिंग
निश्चित स्थिर होने के बजाय, यह एक निश्चित न्यूनतम होना चाहिए ।
आपका पासवर्ड हैश फ़ंक्शन होने के बजाय:
String HashPassword(String password)
{
return BCrypt.HashPassword(password, BCRYPT_DEFAULT_COST);
}
यह कुछ इस तरह होना चाहिए:
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;
}
और आदर्श रूप से यह सभी के बीसीक्रिप्ट लाइब्रेरी का हिस्सा होगा, इसलिए समय-समय पर लागत में वृद्धि करने के लिए पुस्तकालय के उपयोगकर्ताओं पर निर्भर होने के बजाय, लागत समय-समय पर स्वयं बढ़ जाती है।