Development Tip

bcrypt는 어떻게 내장 솔트를 가질 수 있습니까?

yourdevel 2020. 10. 3. 12:02
반응형

bcrypt는 어떻게 내장 솔트를 가질 수 있습니까?


Coda Hale의 기사 "암호를 안전하게 저장하는 방법" 은 다음과 같이 주장합니다.

bcrypt에는 레인보우 테이블 공격을 방지하기 위해 내장 된 솔트가 있습니다.

그는 OpenBSD의 구현에서 다음 같이 말하는 이 논문을 인용 합니다bcrypt .

OpenBSD는 arcfour (arc4random (3)) 키 스트림에서 128 비트 bcrypt 솔트를 생성하고 커널이 장치 타이밍에서 수집 한 임의의 데이터로 시드됩니다.

나는 이것이 어떻게 작동 할 수 있는지 이해하지 못한다. 소금에 대한 나의 개념에서 :

  • 저장된 비밀번호마다 달라야하므로 각각에 대해 별도의 레인보우 테이블을 생성해야합니다.
  • 반복 할 수 있도록 어딘가에 저장해야합니다. 사용자가 로그인을 시도하면 암호를 시도하고 원래 암호를 저장할 때했던 것과 동일한 솔트 앤 해시 절차를 반복하고 비교합니다.

bcrypt와 함께 Devise (Rails 로그인 관리자)를 사용할 때 데이터베이스에 솔트 열이 없기 때문에 혼란 스럽습니다. 솔트가 무작위이고 어디에도 저장되지 않은 경우 어떻게 해싱 프로세스를 안정적으로 반복 할 수 있습니까?

간단히 말해서, bcrypt가 어떻게 내장 솔트를 가질 수 있습니까?


이것은 bcrypt입니다.

무작위 소금을 생성합니다. "비용"요소가 사전 구성되었습니다. 암호를 수집하십시오.

솔트 및 비용 요소를 사용하여 암호에서 암호화 키를 가져옵니다. 잘 알려진 문자열을 암호화하는 데 사용합니다. 비용, 솔트 및 암호 텍스트를 저장 하십시오 . 이 세 가지 요소는 길이를 알고 있기 때문에 쉽게 연결하고 단일 필드에 저장하지만 나중에 분리 할 수 ​​있습니다.

누군가 인증을 시도하면 저장된 비용과 솔트를 검색합니다. 입력 된 암호, 비용 및 솔트에서 키를 가져옵니다. 잘 알려진 동일한 문자열을 암호화합니다. 생성 된 암호 텍스트가 저장된 암호 텍스트와 일치하면 암호가 일치합니다.

Bcrypt는 PBKDF2와 같은 알고리즘을 기반으로하는보다 전통적인 체계와 매우 유사한 방식으로 작동합니다. 주요 차이점은 알려진 일반 텍스트를 암호화하기 위해 파생 키를 사용한다는 것입니다. 다른 체계는 (합리적으로) 키 파생 기능이 되돌릴 수 없다고 가정하고 파생 된 키를 직접 저장합니다.


데이터베이스에 저장되는 bcrypt"해시"는 다음과 같습니다.

$ 2a $ 10 $ vI8aWBnW3fID.ZQ4 / zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

이것은 실제로 "$"로 구분 된 세 개의 필드입니다.

  • 2a사용 된 bcrypt알고리즘 버전을 식별합니다 .
  • 10비용 요소입니다. 2 키 도출 함수의 10 회 반복이 사용됩니다 (그런데 충분하지 않습니다. 비용은 12 회 이상 권장합니다.)
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa수정 된 Base-64로 연결 및 인코딩 된 솔트 및 암호 텍스트입니다. 처음 22자는 솔트에 대해 16 바이트 값으로 디코딩됩니다. 나머지 문자는 인증을 위해 비교할 암호 텍스트입니다.

이 예제는 Coda Hale의 루비 구현 문서 에서 가져 왔습니다 .


나는 그 문구가 다음과 같이 표현되어야한다고 믿는다.

bcrypt에는 레인보우 테이블 공격을 방지하기 위해 생성 된 해시솔트가 내장되어 있습니다.

bcrypt유틸리티 자체는 소금의 목록을 유지하기 위해 표시되지 않습니다. 오히려 솔트는 무작위로 생성되고 함수의 출력에 추가되어 나중에 기억되도록합니다 ( 의 Java 구현에bcrypt 따라 ). 다시 말해,에서 생성 된 "해시" bcrypt단순한 해시 가 아닙니다 . 오히려 해시 솔트가 연결됩니다.


이것은 Spring Security의 PasswordEncoder 인터페이스 문서에서 가져온 것입니다.

 * @param rawPassword the raw password to encode and match
 * @param encodedPassword the encoded password from storage to compare with
 * @return true if the raw password, after encoding, matches the encoded password from
 * storage
 */
boolean matches(CharSequence rawPassword, String encodedPassword);

즉, 사용자가 다음에 로그인 할 때 다시 입력 할 rawPassword와 일치해야하며 이전 로그인 / 등록 중에 데이터베이스에 저장되어있는 Bcrypt 인코딩 된 암호와 일치해야합니다.

참고 URL : https://stackoverflow.com/questions/6832445/how-can-bcrypt-have-built-in-salts

반응형