최적의 bcrypt 작업 요소


81

암호 해싱에 이상적인 bcrypt 작업 요소는 무엇입니까?

10의 요소를 사용하면 랩톱에서 암호를 해시하는 데 약 0.1 초가 걸립니다. 우리가 매우 바쁜 사이트로 끝나면 사람들의 암호를 확인하는 작업으로 바뀝니다.

작업 계수 7을 사용하여 총 암호 해시 작업을 랩톱 로그인 당 약 .01 초로 줄이는 것이 더 낫습니까?

무차별 대입 안전과 운영 비용 간의 균형을 어떻게 결정합니까?


7
비용은 오프라인 공격을 방해합니다. "온라인"인 경우 서비스 거부 공격을 방지하기 위해 시도 사이에 최소 지연 시간 (예 : 5 초)을 사용할 수 있습니다.
Ian Boyd


1
: 사람이 관심이 들어, 난 그냥 (보안, 서버 부하 및 응답 배의 균형을위한 분명히 중요하다) 서버에서 테스트 bcrypt 성능에 작은 자바 CLI 도구 쓴 github.com/cdraeger/hash-performance
의 Blacklight

답변:


103

값은 비밀번호에 저장됩니다 $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 인 사람을 저장할 수 없습니다.


8
이것은 정말 훌륭한 대답입니다. 나는 로그인 아이디어에서 re-crypt를 고려하지 않았습니다. 정말 고맙습니다!
크리스

1
암호 해독은 어떻게 작동합니까? 이전 bcrypt 작업 비용을 어딘가에 저장해야 로그인에 사용할 수 있으며 암호를 확인한 후 데이터베이스의 해시와 비용을 업데이트 할 수 있습니까?
Jerry Saravia

6
@JerrySaravia bcrypt의 장점은 비용이 해시 자체에 저장된다는 입니다. 따라서 추가로 아무것도 저장할 필요가 없습니다 . 현재 해시로 인증 한 다음 즉시 다른 비용으로 해시를 다시 생성하십시오. 단순한!
Mark Locker

@MarkLocker, 감사합니다 마크! B [아름다운] 토굴입니다! 그러나 진지하게, 그것은 일을 훨씬 쉽게 만들고 놀라운 일입니다.
Jerry Saravia

"답장을 잘못 시도"했기 때문에 편집 할 수 없기 때문에 (내 편집 내용을 읽었습니까?) 대신 정보에 주석을 달도록 허용하십시오. 값 예 : $2y$08$fJS4yx0i8kiOzIBIamZ51OWTMrzyE/4je34Oxhw.5xxp3Es7Ke32W. 편집을 시도한 이유 : "2 문자 작업"이 숫자인지 16 진수인지 여부가 확실하지 않아 테스트해야했습니다. 다음은 다른 모든 사람에 대한 테스트 결과이므로 직접 시도 할 필요가 없습니다.

3

짧은 버전

계산에 최소 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 라이브러리의 일부이므로 주기적으로 비용을 증가시키기 위해 라이브러리 사용자에게 의존하는 대신 비용이 주기적으로 증가합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.