암호 해싱에 이상적인 bcrypt 작업 요소는 무엇입니까?
10의 요소를 사용하면 랩톱에서 암호를 해시하는 데 약 0.1 초가 걸립니다. 우리가 매우 바쁜 사이트로 끝나면 사람들의 암호를 확인하는 작업으로 바뀝니다.
작업 계수 7을 사용하여 총 암호 해시 작업을 랩톱 로그인 당 약 .01 초로 줄이는 것이 더 낫습니까?
무차별 대입 안전과 운영 비용 간의 균형을 어떻게 결정합니까?
답변
값은 비밀번호에 저장됩니다 $2a$(2 chars work)$(22 chars salt)(31 chars hash)
. 고정 된 값이 아닙니다.
부하가 너무 높으면 다음에 로그인 할 때 더 빨리 계산할 수 있도록 암호화하십시오. 마찬가지로, 시간이 지남에 따라 더 나은 서버를 얻을 수있을 때로드가 문제가되지 않으면 로그인 할 때 해시의 강도를 업그레이드 할 수 있습니다.
비결은 무어의 법칙과 함께 대략 같은 시간을 미래에 영원히 걸리게하는 것입니다. 숫자는 log2이므로 컴퓨터의 속도가 두 배가 될 때마다 기본 숫자에 1을 더합니다.
사용자의 암호를 강제로 강제하는 데 걸리는 시간을 결정하십시오. 예를 들어, 몇 가지 일반적인 사전 단어의 경우, 귀하의 계정 생성은 이미 암호가 약하다고 경고했을 것입니다. 예를 들어 1000 개의 일반적인 단어 중 하나이고 공격자가 각각을 테스트하는 데 0.1 초가 걸리면 100 개를 구매합니다 (글쎄, 일부 단어는 더 일반적입니다 …). 사용자가 ‘공통 사전 단어’+ 2 개의 숫자를 선택하면 2 시간이 넘습니다. 암호 데이터베이스가 손상되고 공격자가 하루에 수백 개의 암호 만 얻을 수있는 경우 대부분의 사용자는 암호를 안전하게 변경하기 위해 몇 시간 또는 며칠을 구입 한 것입니다. 시간을 사는 문제입니다.
http://www.postgresql.org/docs/8.3/static/pgcrypto.html 은 암호 크래킹을 고려할 때가 있습니다. 물론 그들이 나열한 암호에는 임의의 문자가 있습니다. 사전에 나오는 단어들 … 사실상 당신은 암호가 12345 인 사람을 저장할 수 없습니다.
답변
짧은 버전
계산에 최소 250ms를 제공하는 반복 횟수
긴 버전
BCrypt가 처음 출판 된 1999 년에 그들은 구현의 기본 비용 요소를 나열했습니다.
- 일반 사용자 : 6
- 슈퍼 유저 : 8
bcrypt 비용 6 은 64 라운드 (2 6 = 64)를 의미합니다.
또한 다음 사항에 유의합니다.
물론, 사람들이 선택한 비용은 수시로 재평가되어야합니다.
- 1976 년 배포 당시 crypt는 초당 4 개 미만의 암호를 해시 할 수있었습니다. (암호 당 250ms)
- 1977 년 VAX-11 / 780에서 crypt (MD5)는 초당 약 3.6 회 평가 될 수있었습니다. (암호 당 277ms)
이는 원래 구현자가 작성했을 때 고려했던 지연의 종류를 제공합니다.
- 일반 사용자의 경우 ~ 250ms
- 수퍼 유저의 경우 ~ 1 초
하지만 물론 오래 서있을수록 좋습니다. 내가 본 모든 BCrypt 구현 10
이 기본 비용으로 사용 되었습니다. 그리고 내 구현 은 그것을 사용했습니다. 기본 비용을 12로 늘려야 할 때라고 생각합니다.
해시 당 250ms 이상을 목표로하기로 결정했습니다.
내 데스크탑 PC는 3.50GHz에서 Intel Core i7-2700K CPU입니다. 저는 원래 2014 년 1 월 3 일에 BCrypt 구현을 벤치마킹했습니다.
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;
}
이상적으로 이것은 모든 사람의 BCrypt 라이브러리의 일부이므로 주기적으로 비용을 증가시키기 위해 라이브러리 사용자에게 의존하는 대신 비용이 주기적으로 증가합니다.