분류 php

비밀번호 해싱 : 암호화 또는 키 해시?

컨텐츠 정보

  • 조회 348 (작성일 )

본문

암호를 올바르게 해시/보호하는 방법은 수십 년 동안 논의 주제였습니다. 

스티브 벨로 빈 (Steve Bellovin)의 Bugtraq에 대한 이 고대 게시물부터 현대의 비밀번호 해싱 경쟁 등에 이르기까지.


오늘날에는 암호를 적어도 적절하게 해시 하는 것이 표준이 되어야 합니다. 예를 들어, PHP는 복잡한 주제에 대한 깊은 이해 없이 개발자에게 친숙하고 사용하기 쉬운 암호 해싱 (@ircmaxell!)을 제공하는 최초의 주류 언어였습니다. passwords_hash() (및 관련 함수)를 사용하면 누구나 쉽게 사용할 수 있습니다.


http://timoh6.github.io/2019/08/19/Password-hashing-Encrypted-or-keyed-hashes.html 


후추가 더 필요하세요? 


비밀번호 보안은 비밀번호 또는 키 확장량과 password/passphrase 자체의 품질을 합한 것입니다. 암호를 추측 할 수 없는 경우 이 조합이 완벽 할 수 있습니다. 그러나 모든 암호에 이 특수 속성이 있는 것은 아닙니다.


암호 해시 작업 요소 설정을 늘리고 암호 해시를 "크랙 불가"로 설정하면 서버 측 암호 보안을 어느 정도 향상 시킬 수 있습니다.


이것은 해시를 암호화하거나 키잉하여 수행 할 수 있습니다. 적에게 이 키 또는 "로컬 매개 변수"또는 "고추"가 없다면 (아마도 소금에 절인) 아마도 크래킹 과정을 시작할 수 없습니다.


이 비밀 키는 해시와 별도로 구성 파일에 저장됩니다. 아이디어는 암호 해시 데이터베이스가 누출되지만 (예 : SQL 주입) 키를 보유한 구성 파일이 위반되지 않으면 공격자가 해시를 크래킹 할 수 없다는 것입니다.


키는 암호화 품질 키 (예 : 256 비트 CSPRNG 출력) 여야 합니다. 이런 종류의 키는 키가 없으면 해시를 크래킹하는 것을 불가능 하게 합니다.


열쇠가 없으면? 


악마는 세부 사항에 있습니다. 이러한 암호화 된 (또는 키가 있는) 해시가 크래킹 될 수 있다는 것은 의심의 여지가 없지만 비밀 키를 비밀로 유지하는 것이 문제입니다.


가장 먼저 할 일은 비밀 키가 해시와 같은 곳에 있지 않은지 확인하는 것입니다. 응용 프로그램의 소스 파일과 데이터베이스는 시작하기 어려운 것입니다. 이것은 소량의 심층 방어를 구입합니다.


응용 프로그램에서 키를 읽을 수 없으면 더 많은 것을 얻을 수 있습니다. 이는 응용 프로그램 서버에서 쿼리 하는 별도의 컴퓨터 또는 가상 컴퓨터 인스턴스를 사용하여 수행됩니다.


예를 들어, 별도의 시스템은 비밀번호 해시를 암호화하고 출력 만 애플리케이션 서버로 리턴합니다 (비밀번호를 검증 할 때 페이 로드를 해독하고 해시를 리턴 한 다음 애플리케이션 서버에서 확인 함).


이 설정은 데이터베이스 유출과 응용 프로그램 서버의 소스 코드 유출을 허용 할 수 있기 때문에 보안 마진이 더 높아집니다 (대화자에게는 암호화 된 해시가 있지만 해독하는 열쇠는 아님).


해시 키잉 또는 암호화 


비밀 키를 해시에 추가하는 방법에는 기본적으로 네 가지가 있습니다.


  • Encrypt the password hash output (키를 쉽게 업데이트하고 비밀번호 해시 작업 요소 업데이트를 허용하며 기존 시스템에 쉽게 통합 할 수 있음)
  • MAC the password hash output (핵심 업데이트에는 더 많은 작업이 필요하며 사용자 상호 작용없이 암호 해시 작업 요소 업데이트를 허용하지 않고 기존 시스템에 쉽게 통합 할 수 있음)
  • Encrypt the password, then password hash the keyed output (사용자 상호 작용 없이 키 업데이트를 허용하지 않고 비밀번호 해시 작업 요소 업데이트를 허용하며 사용자 상호 작용 없이 기존 시스템에 통합 할 수 없음).
  • MAC the password, then password hash the keyed output (사용자 상호 작용없이 키 업데이트를 허용하지 않고 사용자 상호 작용 없이 비밀번호 해시 작업 요소 업데이트를 허용하지 않으며 사용자 상호 작용 없이 기존 시스템에 통합 할 수 없음).

그러나 일반적인? 간단한 방법은 암호에 키를 추가하거나 추가하고 연결 결과를 해싱 함수에 제공하는 것입니다.


이는 MAC에 암호를 입력 한 다음 키 출력을 암호로 해시 하는 “깨진 방법”입니다. 이것은 적어도 bcrypt 알고리즘에서 실제 문제를 제기합니다. Bcrypt는 72 바이트보다 긴 문자열을 처리하지 않으며 추가 바이트는 무시됩니다. 이것은 키 앞에 비밀번호가 추가 된 경우 문제가 될 수 있으며 추가 된 경우 키가 약화 될 수 있습니다.


HMAC와 같은 적절한 MAC 알고리즘을 사용하여 올바른 키 입력 방법을 수행 할 수 있습니다.

<?php
$keyed_password = hash_hmac('sha256', $password, $secret_key);
$hashed_password = password_hash($keyed_password, PASSWORD_DEFAULT, $options);
?>

이것은 더 나은 접근 방법이지만 키와 비밀번호가 혼합되어 사용자 상호 작용 없이 키를 업데이트 할 수 없도록 하는 효과가 있습니다 (사용자는 새 해시를 생성하기 전에 비밀번호를 입력해야 합니다). 기존의 키가 없는 해시 키잉에도 동일하게 적용되므로 사용자가 암호를 입력해야 암호를 얻을 수 있습니다.

비밀번호 해시 출력이 암호화 (또는 키 입력) 된 경우 사용자의 상호 작용 없이 비밀 키를 업데이트 할 수 있습니다. 따라서 이와 관련하여 암호 해시 출력에서 ​​작동하는 것이 좋습니다. 그러나 해시 출력이 암호화 또는 MAC 된 경우 어떤 차이가 있습니까?


한 가지 차이점은 유지 관리 요구 사항입니다. 키를 업데이트 해야 하거나 다른 키를 가진 다른 데이터베이스를 병합 해야 하는 경우 해시 출력 키를 사용하려면 "키 버전"(암호 처리 코드에서 고려 해야 하는 해시와 함께)을 사용하고 저장해야 합니다.


비밀번호 해시 출력이 암호화 된 경우 이 추가 작업이 필요하지 않습니다. 암호화 된 해시는 새 키를 사용하여 다시 해독하고 암호화 할 수 있으며 이전 키는 즉시 버릴 수 있습니다.


해시를 암호화하면 데이터베이스의 솔트 및 기타 해시 매개 변수도 숨겨집니다.


그리고 비밀번호 해시 출력에서 ​​작동하고 암호화로 이를 수행 할 때 비밀번호 해싱 알고리즘이 해당 기능을 지원하는 경우 (Argon2 및 bcrypt는 지원하지 않지만, 예를 들어, 비밀번호 해싱 기능의 작업 요소 설정은 사용자 비밀번호 없이 증가 할 수 있습니다. yescrypt 않습니다).


결론 


비밀 키를 애플리케이션 소스 코드의 해시와 분리하면서 해시 출력을 암호화하면 보안 마진이 약간 증가 할 수 있습니다.


비밀 키가 최소한 응용 프로그램 서버 (및 데이터베이스 서버)와 별도의 서버 인스턴스에 유지되고 암호화 / 암호 해독 프로세스를 수행하고 비밀 키를 응용 프로그램 서버에 노출 시키지 않으면 더 큰 이득을 얻을 수 있습니다.


“추가 비밀”매개 변수가 있는 최신 비밀번호 해싱 기능 (Argon2와 같은)에 대한 참고 사항. 비밀 키는 추가 매개 변수로 Argon2에 자연스럽게 입력 될 수 있으므로 수동 키잉이 필요하지 않습니다. 그러나 이를 최대한 활용하려면 암호 처리 코드가 "별도의 인스턴스"에 있어야 합니다 (키를 Argon2 기능으로 다르게 설정할 수 없으므로 앱 서버 및 데이터베이스와 분리). 기존 시스템에서 구현하는 데 더 많은 작업이 필요하며 사용자 상호 작용 없이 비밀 키를 업데이트 할 수 없습니다.


추가 보안 여유가 필요한 경우 암호 해시 출력을 암호화하는 것이 좋습니다.


결국 그것은 단순성 / 자원과 추가 보안 마진 사이의 균형입니다.