사용자 암호 정리


98

사용자가 제공 한 암호를 해시하고 데이터베이스에 저장하기 전에 어떻게 이스케이프하거나 정리해야합니까?

PHP 개발자는 보안 목적으로 사용자의 암호를 해싱하는 것을 고려할 때 종종 다른 사용자가 제공 한 데이터처럼 해당 암호를 생각하는 경향이 있습니다. 이 주제는 암호 저장과 관련된 PHP 질문에서 자주 등장합니다. 개발자는 종종 escape_string()(다양한 반복에서) htmlspecialchars(), addslashes()및 기타 기능을 사용하여 암호를 정리하고 해싱하고 데이터베이스에 저장하기를 원합니다 .


1
사용자는 base64로 인코딩 할 수 있습니다
MSS

@MSS가 없습니다 . base64가 암호화 또는 해싱이 아닌 인코딩 이기 때문에 사용 해서는 안됩니다 . 암호는 항상 해시 되어야 합니다 .
Jay Blanchard

1
나는 해시 전에 의미합니다;)
MSS

해싱하기 전에 그렇게해서는 안되며 그렇게 할 필요도 없습니다. 그것은 당신이 불필요한 추가 코드 @MSS 작성해야 발생할 수 있습니다
제이 블랜차드

답변:


99

password_hash()여러 가지 이유로 PHP로 해싱 할 비밀번호에 대해 다른 정리 메커니즘을 이스케이프, 트리밍 또는 사용해서는 안됩니다. 가장 큰 이유는 비밀번호를 추가로 정리하려면 불필요한 추가 코드가 필요하기 때문입니다.

우리는 모든 사용자 입력을 정리해야하며 우리가 사용자로부터받는 다른 모든 정보에 대해 귀하가 옳다고 주장 할 것입니다 (그리고 귀하의 시스템에서 사용자 데이터가 허용되는 모든 게시물에서 볼 수 있습니다). 암호가 다릅니다. 해시 된 암호는 데이터베이스에 저장하기 전에 문자열이 해시로 바뀌기 때문에 SQL 주입 위협을 제공 할 수 없습니다.

암호 해싱 작업은 암호를 데이터베이스에 안전하게 저장하는 작업입니다. 해시 함수는 바이트에 특별한 의미를 부여하지 않으므로 보안상의 이유로 입력을 정리할 필요가 없습니다.

사용자가 원하는 암호 / 구문 을 사용할 수 있도록 허용하는 만트라를 따르고 암호를 제한하지 않고 길이, 공백 및 특수 문자 해싱을 허용하면 내용이 무엇이든간에 암호 / 암호를 안전하게 만들 수 있습니다. 비밀번호. 현재 가장 일반적인 해시 (기본값) 인은 (는) PASSWORD_BCRYPT해시 된 암호 정보 및 비용 (해시 생성의 알고리즘 비용)과 함께 임의의 솔트를 포함하는 60 자 폭의 문자열로 암호를 변환합니다.

PASSWORD_BCRYPT는 CRYPT_BLOWFISH 알고리즘을 사용하여 새 암호 해시를 만드는 데 사용됩니다. 이렇게하면 항상 폭이 항상 60자인 "$ 2y $"암호화 형식을 사용하는 해시가 생성됩니다.

해시를 저장하기위한 공간 요구 사항 때문에 같은 저장된 해시의 열 유형에 더 큰 이동하는 것이 낫다, 다른 해싱 방법은 함수에 추가됨에 따라 변경 될 수 있습니다 VARCHAR(255)또는 TEXT.

완전한 SQL 쿼리를 암호로 사용할 수 있으며 해시되어 SQL 엔진에서 실행할 수 없게됩니다. 예 :

SELECT * FROM `users`;

해시 될 수 있습니다. $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G

다양한 삭제 방법이 비밀번호에 어떤 영향을 미치는지 살펴 보겠습니다.

암호는 I'm a "dessert topping" & a <floor wax>!(여기에 표시되지 않는 암호 끝에 5 개의 공백이 있습니다.)

다음 트리밍 방법을 적용하면 약간의 다른 결과가 나타납니다.

var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));

결과 :

string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // double quotes, ampersand and braces have been changed
string(65) "I'm a &quot;dessert topping&quot; &amp; a &lt;floor wax&gt;!     " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>!     " // escape characters have been added
string(34) "I'm a "dessert topping" & a !     " // looks like we have something missing

이것들을 보내면 password_hash()어떻게 되나요? 위의 쿼리처럼 모두 해시됩니다. 암호를 확인하려고 할 때 문제가 발생합니다. 이러한 방법 중 하나 이상을 사용하는 경우 .NET과 비교하기 전에 다시 사용해야합니다 password_verify(). 다음은 실패합니다.

password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query

게시 된 암호는 암호 확인에 사용하기 전에 선택한 정리 방법을 통해 실행해야합니다. 불필요한 단계 집합이며 해시를 더 좋게 만들지 않습니다.


5.5 미만의 PHP 버전을 사용하십니까? password_hash() 호환성 팩을 사용할 수 있습니다 .

정말 MD5 암호 해시를 사용해서는 안됩니다 .


13
그는 허용 후행 공백 자신의 암호를 만들어 제 경우에, 그는 로그인 @DanBracuk에 그들을 사용해야합니다
제이 블랜차드

12
@DanBracuk는 어떻습니까? 사용자가 앞 / 뒤 공백을 포함하여 원하는 암호를 설정하도록 허용하면?
Jay Blanchard

16
그렇기 때문에 대부분의 경우 선택한 암호를 두 번 입력해야합니다. 사용자가 실수로 공간을 추가하면 더 이상 추가하기 전에 알아낼 것입니다. 사용자가 문제가 아닌 것보다 고의로 한 경우.
곰과 레슬링 한 적이 있습니다.

4
@MargaretBloom, 경험 법칙은 휴리스틱입니다. 우리는 때때로 암호와 같이 생각할 필요가 있습니다. 당신은 "아무도 미래에 상황이 어떻게 변할지 모른다"라고 말하지만, 어떤 것이 변경 될 경우 우리가 데이터를 데이터베이스에 넣기 전에 데이터를 이스케이프하는 방법 인 것 같습니다.이 경우 사용자는 비밀번호가 입력되지 않았을 때 잠금 상태가됩니다. 더 이상 우리가 저장 한 것과 일치합니다. 암호 해시를 이스케이프하지 않을 때의 위험과 이스케이프의 위험은 무엇입니까?
DavidS

3
정확합니다 : 물론 매개 변수화 된 SQL 쿼리에 올바르게 전달한다는 제한된 의미에서 "해시를 이스케이프"합니다. 여기서 SQL 커넥터의 일부 코드는 "이스케이프"에 해당하는 작업을 수행하거나 수행하지 않을 수 있습니다. t 알고 상관하지 않습니다. 이를 달성하기 위해 특정 코드를 작성할 필요가 없습니다. 이전에 인생 결정을 잘못 내리지 않은 한 모든 SQL 쿼리에 대해 완전히 일상적인 작업이기 때문입니다.
Steve Jessop

36

암호를 해싱하기 전에 RFC 7613의 섹션 4에 설명 된대로 정규화해야합니다 . 특히:

  1. 추가 매핑 규칙 : ASCII가 아닌 공간의 모든 인스턴스는 반드시 ASCII 공간 (U + 0020)으로 매핑되어야합니다. 비 ASCII 공간은 유니 코드 일반 범주가 "Zs"(U + 0020 제외) 인 유니 코드 코드 포인트입니다.

과:

  1. 정규화 규칙 : 모든 문자에 유니 코드 NFC (Normalization Form C)를 적용해야합니다.

이렇게하면 사용자가 동일한 암호를 입력하지만 다른 입력 방법을 사용하는 경우에도 암호를 수락해야합니다.


3
@DavidS, 매우 반짝이는 북미 Mac Book (Jo가 떠나기 직전에 사용)과 국제화가 잘되지 않은 대만 인터넷 카페 컴퓨터 (Jo가 다운로드하기 위해 사용하려는 것은 비행기 탑승 카드입니다).
Margaret Bloom

2
징그럽게 들립니다. :-) 그래도 고마워.
DavidS

3
흠. 이렇게하면 아직 할당되지 않은 문자가 포함 된 모든 것을 거부하도록 암호의 유효성을 검사해야합니다. 사용자가 앱이 인식하지 못하여 그대로 해시하는 NEWFANGLED SPACE를 사용하고 유니 코드 문자 데이터베이스를 업그레이드하고 갑자기 NEWFANGLED SPACE가 해싱 전에 SPACE에 매핑되면 끔찍할 것입니다. 앱에서 이전 해시로 해시 할 비밀번호를 더 이상 입력 할 수 없습니다.
ruakh

4
@JayBlanchard 한 컴퓨터에서 스페이스 바를 누르고 다른 컴퓨터에서 누르면 두 개의 다른 유니 코드 코드 포인트가 표시되고 사용자가 아무것도 알지 못하는 사이에 두 개의 다른 UTF-8 인코딩을 갖게되기 때문입니다. 이것은 무시하고 싶은 문제라고 주장 할 수 있지만 RFC 7613은 그러한 실제 문제에서 비롯된 것이지 메이크 워크 권장 사항이 아닙니다.
분석 재개 모니카

1
@ruakh 특정 방식으로 암호를 처리하기로 결정한 후에는 해당 방식으로 처리해야합니다. 그렇지 않으면 기존 사용 사례에서 문제가 발생합니다. 나중에 전처리 방법을 변경하려는 경우 비밀번호의 전처리 및 해시 표현과 함께 저장해야합니다. 이런 식으로 입력을 받으면 비교 대상에 따라 전처리 / 해싱 방법을 선택합니다.
분석 재개 모니카
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.