안전한 비밀번호 해싱

내 애플리케이션 사용자가 제공한 암호를 해시해야 하는 이유는 무엇입니까?

암호 해싱은 사용자의 암호를 허용하는 응용 프로그램을 설계할 때 가장 기본적인 보안 고려 사항 중 하나입니다. 해싱을 사용하지 않으면 데이터베이스가 손상된 경우 애플리케이션 데이터베이스에 저장된 모든 비밀번호를 도용할 수 있으며 고유한 비밀번호를 사용하지 않는 경우 애플리케이션뿐만 아니라 다른 서비스의 사용자 계정도 즉시 손상시키는 데 사용할 수 있습니다.

사용자 암호를 데이터베이스에 저장하기 전에 해싱 알고리즘을 적용하면 공격자가 원래 암호를 확인하는 것이 불가능하게 하면서도 결과 해시를 나중에 원래 암호와 비교할 수 있습니다.

그러나 해싱 암호는 데이터 저장소에서 암호가 손상되지 않도록 보호할 뿐이며 응용 프로그램 자체에 삽입된 악성 코드가 암호를 가로채는 것을 반드시 보호하지는 않습니다.

md5sha1과 같은 일반적인 해싱 함수가 암호에 적합하지 않은 이유는 무엇입니까?

MD5, SHA1 및 SHA256과 같은 해싱 알고리즘은 매우 빠르고 효율적으로 설계되었습니다. 현대 기술과 컴퓨터 장비를 사용하면 원래 입력을 결정하기 위해 이러한 알고리즘의 출력을 "무차별 대입"하는 것이 간단해졌습니다.

최신 컴퓨터가 이러한 해싱 알고리즘을 "역전"할 수 있는 속도 때문에 많은 보안 전문가는 암호 해싱 사용을 강력히 제안합니다.

일반적인 해시 함수가 적합하지 않은 경우 비밀번호를 어떻게 해시해야 합니까?

암호를 해싱할 때 가장 중요한 두 가지 고려 사항은 계산 비용과 소금입니다. 계산 비용이 더 많이 드는 해싱 알고리즘일수록 출력을 무차별 대입하는 데 더 오래 걸립니다.

PHP는 안전한 방식으로 비밀번호 해싱확인을 모두 안전하게 처리하는 기본 비밀번호 해싱 API를 제공합니다.

또 다른 옵션은 여러 해싱 알고리즘을 지원하는 crypt() 함수입니다. 이 기능을 사용할 때, PHP에는 지원되는 각 알고리즘의 기본 구현이 포함되어 있으므로 선택한 알고리즘을 사용할 수 있다는 것이 보장됩니다.

암호를 해싱할 때 사용하도록 제안된 알고리즘은 Blowfish입니다. 이는 암호 해싱 API에서 사용하는 기본값이기도 합니다. 이는 MD5 또는 SHA1보다 계산 비용이 훨씬 높지만 여전히 확장 가능하기 때문입니다.

crypt()를 사용하여 암호를 확인하는 경우 일정한 시간 문자열 비교를 사용하여 타이밍 공격을 방지하도록 주의해야 합니다. PHP의 == 및 === 연산자도 strcmp()도 상수 시간 문자열 비교를 수행하지 않습니다. password_verify()가 이 작업을 수행하므로 가능하면 기본 암호 해싱 API를 사용하는 것이 좋습니다.

salt란 무엇입니까?

암호화 솔트는 레인보우 테이블로 알려진 미리 계산된 해시 및 해당 입력 쌍의 목록에서 출력을 조회할 가능성을 제거하기 위해 해싱 프로세스 중에 적용되는 데이터입니다.

더 간단한 용어로, 소금은 해시를 크랙하기 훨씬 더 어렵게 만드는 약간의 추가 데이터입니다. 사전 계산된 해시의 광범위한 목록과 해당 해시에 대한 원래 입력을 제공하는 온라인 서비스가 많이 있습니다. 솔트를 사용하면 이러한 목록 중 하나에서 결과 해시를 찾는 것이 불가능하거나 불가능합니다.

password_hash()는 제공되지 않는 경우 임의의 솔트를 생성하며 일반적으로 이것이 가장 쉽고 안전한 접근 방식입니다.

salts를 어떻게 보관합니까?

password_hash() 또는 crypt()를 사용할 때 반환 값에는 생성된 해시의 일부로 소금이 포함됩니다. 이 값은 사용된 해시 함수에 대한 정보를 포함하고 암호를 확인할 때 password_verify() 또는 crypt()에 직접 제공될 수 있으므로 데이터베이스에 그대로 저장해야 합니다.

다음 다이어그램은 crypt() 또는 password_hash()의 반환 값 형식을 보여줍니다. 보시다시피 알고리즘에 대한 모든 정보와 향후 암호 확인에 필요한 솔트가 포함된 독립형입니다.

password_hash 및 crypt에 의해 반환된 값의 구성 요소: 선택한 알고리즘, 알고리즘 옵션, 사용된 솔트 및 해시된 암호의 순서입니다.