문제

사용자가 가입하는 PHP 웹 사이트를 만들고 있으며 "이메일 확인"코드에 대한 모범 사례에 대해 궁금합니다.

신규 사용자는 이메일 주소를 확인해야합니다. 코드를 생성하여 이메일로 사용자에게 보내어 계정을 활성화하는 데 사용할 수 있습니다. 이 키를 데이터베이스에 저장하는 대신 편리한 작은 해결 방법을 사용하고 있습니다. 코드는 다음의 결과입니다.

md5("xxxxxxxxx".$username."xxxxxxxxxxx".$timestamp."xxxxxxxxx");

여기서 $ timestamp는 사용자 생성 시간을 나타냅니다. 전체적으로 나는 이것에 매우 만족했지만, 나는 생각하게되었고, 이것은 충분히 안전합니까? 그리고 충돌 가능성은 어떻습니까? 또한 비밀번호 재설정 코드 등을 생성해야합니다. 유사한 방법론을 사용하는 경우 충돌로 인해 한 사용자가 다른 사용자의 비밀번호를 실수로 재설정 할 수 있습니다. 그리고 그것은 좋지 않습니다.

그래서 어떻게 이런 일을합니까? 내 생각은 다음 형식의 테이블이었습니다.

codePK (int, a-I), userID (int), type (int), code (varchar 32), date (timestamp)

'type'이 "활성화", "이메일 변경"또는 "비밀번호 재설정"을 의미하는 1, 2 또는 3 인 경우. 이것이 좋은 방법입니까? 더 나은 방법이 있습니까?

위와 유사한 방법을 사용하여 Cron-Jobs를 사용하지 않고 이틀 동안 무엇을 자동으로 삭제할 수 있습니까? 내 호스트 (거의 freespeech.net)는 그들을 지원하지 않습니다. 가능하다면 외부 호스트에 cron-job가있는 것을 피하고 싶습니다.

감사!
말라

업데이트:
명확히하기 위해 : 나는이 작업을 안전하게 안전하게 갈 수있는 유일한 방법은 데이터베이스를 사용하는 것입니다. 이것이 원래 기능이 피하려고했던 것입니다. 내 질문은 테이블 (또는 테이블?)을 어떻게 구성 해야하는지에 관한 것입니다. 누군가 내가 Codepk를 없애고 코드를 pk로 만들 것을 제안했습니다. 요컨대, 내 질문은 : 이것이 당신이하는 일입니까?

도움이 되었습니까?

해결책

이런 종류의 트릭이 필요할 때 일반적으로 두 가지 이유 중 하나입니다.

  1. 사용자에게 전송 된 확인 이메일에 사용되는 키로
  2. 비밀번호 리셋 링크에 사용되는 키로

물론 그러한 구조 사용을 고려할 수있는 다른 경우가 많을 것입니다.

우선, 당신은 항상 숨겨져 있고 당신만이 아는 소금을 항상 사용해야합니다. 이 소금은 사용자마다 달라야합니다. 소금은 예를 들어 계산할 수 있습니다 sha256(something random). 그런 다음이 소금은 데이터베이스에 사용자 이름 및 비밀번호 (소금으로 해시)와 함께 저장해야합니다.

비밀번호 재설정 링크를 보낼 때 내가 할 일은 다른 소금을 만드는 것입니다 (사용자에게 소금으로 해시 된 것에 대한 액세스 권한을 부여하지 마십시오. 그는 자신의 암호를 알고 있으므로 Bruteforce를 사용하여 잠재적으로 소금을 알아낼 수 있습니다). 본질적으로 임의의 문자열의 해시 일뿐입니다 (길이가 문제라고 언급했듯이 여기서 MD5로 가고 싶을 수도 있습니다). 그런 다음 데이터베이스에 저장해야합니다.

종종 사용자 테이블에 추가 열을 추가하여 도망 갈 수 있습니다. 그러나 여기에는 몇 가지 문제가 있습니다. 주로 비밀번호가 재설정되거나 사용자가 활성화되면 데이터베이스에서 키를 제거하여 대부분의 행이 널 값을 갖는 결과로 인해 다른 문제가 발생합니다. .

이것이 본질적으로 요약되는 것 :

  • 사용자의 고유 한 소금을 사용하여 사용자의 비밀번호 해시 (그리고 아마도 세계적으로 비밀 소금).
  • 타임 스탬프와 같은 많은 무작위 또는 의사로드 돔 소스를 해싱하여 키를 생성합니다. mt_rand() 또는 Random.org, 당신이 정말로 임의의 물건을 원한다면.
  • 비밀번호 재설정 키, 활성화 키 등을 포함하여 사용자가 액세스 할 수있는 모든 것을 해싱하기 위해 사용자에게 고유 한 글로벌 소금 또는 사용자에게 고유 한 소금을 사용하지 마십시오.

나는 결코 보안 전문가가 아니며, 아마도 많은 것들을 잊어 버렸을 것입니다. 그리고 나는 매우 나쁜 연습을 언급했을 것입니다. 단지 내 5 센트 ;-)

다른 팁

사용자의 데이터를 인증 키의 기초로 사용하는 이유는 무엇입니까?

나는 당신이 데이터베이스에 비활성화 된 데이터를 저장하고 있다고 가정합니다. 그래서 단순히 임의의 키인 추가 레코드를 추가하지 마십시오 (아마도 MD5'ed. uniqid 추가 조작으로) 그리고 그것을 확인한 적이 있습니까?

인터넷에 방법을 게시 할 때까지 충분히 안전했습니다! 이것은 당신이 모호함에 의한 보안에 의존했기 때문입니다. 이것은 좋은 생각이 아닙니다.

당신은 당신에게만 알려진 비밀 키를 통합 한 일종의 키 해시 함수 또는 Mac을 이상적으로 사용해야합니다.

코드 필드를 고유 한 색인으로 만드는 이유는 무엇입니까? 그래서 절대 콜리 나도가 없을까요?

또한 사용자 입력에서 해시를 생성하여 데이터베이스 해시 (이메일 확인, 비밀번호 재설정 등)와 일치시킬 필요가없는 경우 해시 본체에 임의 문자열을 추가 할 수 있습니다.md5('xxx'.$username.'xxx'.time().'xxx'.rand())

사용자에게 사용자 이름을 입력하도록 요청하지 않겠습니까? 그리고 그들의 코드는 충돌 문제를 제거합니까? 이메일에서 얻을 수있는 키를 여전히 요구하기 때문에 보안 상당한 것을 잃지 않지만 다른 사용자의 비밀번호를 재설정 할 수있는 것을 막을 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top