문제

현재 MD5는 부분적으로 안전하지 않다고 합니다.이를 고려하여 비밀번호 보호를 위해 어떤 메커니즘을 사용해야 하는지 알고 싶습니다.

이 질문, 비밀번호를 "이중 해싱"하는 것이 한 번만 해싱하는 것보다 덜 안전합니까? 여러 번 해싱하는 것이 좋은 생각일 수 있다고 제안하지만, 개별 파일에 대한 비밀번호 보호를 구현하는 방법은 무엇입니까? 소금을 사용하는 것이 좋습니다.

저는 PHP를 사용하고 있습니다.안전하고 빠른 비밀번호 암호화 시스템을 원합니다.비밀번호를 백만 번 해싱하는 것이 더 안전할 수도 있지만 속도도 느릴 수 있습니다.속도와 안전 사이의 균형을 잘 맞추는 방법은 무엇입니까?또한 결과가 일정한 수의 문자를 갖는 것을 선호합니다.

  1. 해싱 메커니즘은 PHP에서 사용 가능해야 합니다.
  2. 안전해야 합니다
  3. 소금을 사용할 수 있습니다. (이 경우 모든 소금이 똑같이 좋은가요?좋은 소금을 생성할 수 있는 방법이 없을까요?)

또한 데이터베이스에 두 개의 필드(예: MD5를 사용하는 필드와 SHA를 사용하는 필드)를 저장해야 합니까?더 안전해질까요, 아니면 더 안전하지 않게 될까요?

충분히 명확하지 않은 경우를 대비해 안전하고 빠른 비밀번호 보호 메커니즘을 갖기 위해 사용할 해싱 함수와 좋은 솔트를 선택하는 방법을 알고 싶습니다.

내 질문을 제대로 다루지 않는 관련 질문:

PHP에서 SHA와 MD5의 차이점은 무엇입니까
간단한 비밀번호 암호화
asp.net의 키, 비밀번호를 안전하게 저장하는 방법
Tomcat 5.5에서 솔트된 비밀번호를 어떻게 구현합니까?

도움이 되었습니까?

해결책

부인 성명:이 답변은 2008년에 작성되었습니다.

그 이후로 PHP는 우리에게 password_hash 그리고 password_verify 도입 이후로 ​​권장되는 비밀번호 해싱 및 확인 방법입니다.

그래도 대답의 이론은 여전히 ​​잘 읽혀집니다.

TL;DR

하지 말아야 할 것

  • 사용자가 비밀번호에 입력할 수 있는 문자를 제한하지 마세요.바보들만이 이런 일을 합니다.
  • 비밀번호 길이를 제한하지 마세요.사용자가 supercalifragilisticexpialidocious가 포함된 문장을 원할 경우 해당 문장을 사용하는 것을 막지 마십시오.
  • 사용자의 비밀번호를 일반 텍스트로 저장하지 마세요.
  • 사용자에게 비밀번호를 이메일로 보내지 마세요. 다만 그들이 그것을 잃어버린 경우와 당신이 임시적인 것을 보낸 경우는 제외합니다.
  • 어떤 방식으로든 비밀번호를 기록하지 마십시오.
  • 절대로 비밀번호를 해시하지 마세요. SHA1 또는 MD5 또는 심지어 SHA256! 현대 크래커 각각 초당 600억 및 1,800억 해시를 초과할 수 있습니다.
  • 섞지 마세요 bcrypt와 날것의 해시()의 출력, 16진수 출력을 사용하거나 base64_encode를 사용하십시오.(이는 악성 코드가 있을 수 있는 모든 입력에 적용됩니다. \0 보안을 심각하게 약화시킬 수 있습니다.)

도스

  • 가능하면 scrypt를 사용하세요.할 수 없다면 bcrypt를 사용하세요.
  • SHA2 해시와 함께 bcrypt 또는 scrypt를 사용할 수 없는 경우 PBKDF2를 사용하십시오.
  • 데이터베이스가 손상되면 모든 사람의 비밀번호를 재설정하세요.
  • 합리적인 최소 8~10자 길이를 구현하고 최소 1개의 대문자, 1개의 소문자, 숫자 및 기호를 요구합니다.이렇게 하면 비밀번호의 엔트로피가 향상되어 해독이 더 어려워집니다.(논쟁에 대해서는 "좋은 비밀번호란 무엇입니까?" 섹션을 참조하십시오.)

어쨌든 왜 해시 비밀번호를 사용합니까?

비밀번호 해싱의 목적은 간단합니다.데이터베이스를 손상시켜 사용자 계정에 대한 악의적인 액세스를 방지합니다.따라서 비밀번호 해싱의 목표는 해커나 크래커가 일반 텍스트 비밀번호를 계산하는 데 너무 많은 시간이나 비용을 소비하여 이를 저지하는 것입니다.그리고 시간/비용은 무기고에서 가장 좋은 억제 요소입니다.

사용자 계정에 대해 훌륭하고 강력한 해시를 원하는 또 다른 이유는 시스템의 모든 비밀번호를 변경할 수 있는 충분한 시간을 제공하기 위해서입니다.데이터베이스가 손상된 경우 복구하는 데 충분한 시간이 필요합니다. 최소 데이터베이스의 모든 비밀번호를 변경하지 않으면 시스템을 잠급니다.

Whitehat Security의 CTO인 Jeremiah Grossman은 자신의 블로그에 밝힌 그의 비밀번호 보호를 무차별 대입으로 깨뜨려야 했던 최근 비밀번호 복구 이후:

흥미롭게도 저는 이 악몽을 겪으면서 비밀번호 크래킹, 저장 및 복잡성에 대해 제가 몰랐던 많은 것을 배웠습니다. 저는 왜 비밀번호 저장이 비밀번호의 복잡성보다 훨씬 더 중요한지 이해하게 되었습니다.비밀번호가 어떻게 저장되어 있는지 모른다면 믿을 수 있는 것은 복잡성뿐입니다. 이는 비밀번호 및 암호화 전문가에게는 상식일 수 있지만 일반적인 InfoSec 또는 웹 보안 전문가에게는 매우 의심스럽습니다.

(강조합니다.)

무엇이 만드는가? 좋은 어쨌든 비밀번호?

엔트로피.(나는 Randall의 관점을 전적으로 지지하는 것은 아닙니다.)

간단히 말해서, 엔트로피는 비밀번호 내에서 얼마나 많은 변화가 있는지를 나타냅니다.비밀번호가 소문자 로마자로만 구성된 경우에는 26자만 가능합니다.그다지 변화가 없는 것입니다.36자로 된 영숫자 비밀번호가 더 좋습니다.그러나 기호를 사용하여 대문자와 소문자를 허용하는 것은 대략 96자입니다.그냥 편지보다 훨씬 낫네요.한 가지 문제는 암호를 기억하기 쉽게 만들기 위해 패턴을 삽입하여 엔트로피를 줄이는 것입니다.이런!

비밀번호 엔트로피는 근사치 용이하게.전체 범위의 ASCII 문자(대략 96개의 입력 가능 문자)를 사용하면 문자당 6.6의 엔트로피가 생성됩니다. 이는 비밀번호의 8자에서는 향후 보안을 위해 여전히 너무 낮습니다(52.679비트의 엔트로피).하지만 좋은 소식은 다음과 같습니다.더 긴 비밀번호와 유니코드 문자가 포함된 비밀번호는 실제로 비밀번호의 엔트로피를 증가시키고 해독하기 어렵게 만듭니다.

비밀번호 엔트로피에 대한 더 긴 논의가 있습니다. 암호화폐 스택교환 대지.Google을 잘 검색하면 많은 결과가 나올 것입니다.

댓글에서 @popnoodles와 이야기를 나눴는데, 그는 다음과 같이 지적했습니다. 집행 X개의 문자, 숫자, 기호 등이 포함된 X개의 길이의 비밀번호 정책은 비밀번호 체계를 더욱 예측 가능하게 만들어 실제로 엔트로피를 줄일 수 있습니다.나는 동의한다.Randomess는 가능한 한 정말 무작위이므로 항상 가장 안전하지만 기억에 남는 솔루션은 아닙니다.

제가 아는 한, 세계 최고의 비밀번호를 만드는 것은 Catch-22입니다.기억하기 어렵거나, 예측하기 어렵거나, 너무 짧거나, 유니코드 문자가 너무 많거나(Windows/모바일 장치에서 입력하기 어려움), 너무 길거나 등입니다.우리의 목적에 맞는 비밀번호는 없으므로 Fort Knox에 있는 것처럼 보호해야 합니다.

모범 사례

Bcrypt 및 암호 현재 모범 사례입니다. 스크립트 시간이 지나면 bcrypt보다 나을 것이지만 Linux/Unix 또는 웹 서버에서 표준으로 채택되지 않았으며 알고리즘에 대한 심층적인 리뷰가 아직 게시되지 않았습니다.그러나 여전히 알고리즘의 미래는 유망해 보입니다.Ruby로 작업하는 경우 다음이 있습니다. 스크립트 보석 이것이 도움이 될 것입니다. 이제 Node.js에는 자체적인 기능이 있습니다. 암호 패키지.다음 중 하나를 통해 PHP에서 Scrypt를 사용할 수 있습니다. 스크립트 확장자 또는 리소듐 확장(둘 다 PECL에서 사용 가능).

나는에 대한 문서를 읽는 것이 좋습니다 암호 기능 bcrypt 사용 방법을 이해하고 싶거나 자신만의 방법을 찾고 싶다면 좋은 싸개 또는 다음과 같은 것을 사용하십시오 PHPASS 보다 레거시 구현을 위해.나는 15~18 라운드는 아니더라도 최소 12 라운드의 bcrypt를 권장합니다.

bcrypt가 가변 비용 메커니즘을 사용하여 복어의 주요 일정만 사용한다는 사실을 알게 되었을 때 bcrypt 사용에 대한 마음이 바뀌었습니다.후자를 사용하면 복어의 이미 비용이 많이 드는 키 일정을 늘려 암호를 무차별 대입하는 비용을 늘릴 수 있습니다.

평균 관행

나는 더 이상 이런 상황을 거의 상상할 수 없다. PHPASS PHP 3.0.18부터 5.3까지 지원하므로 상상할 수 있는 거의 모든 설치에서 사용할 수 있으며 그렇지 않은 경우에도 사용해야 합니다. 확실히 알아라 귀하의 환경이 bcrypt를 지원하는지 확인하세요.

하지만 bcrypt나 PHPASS를 전혀 사용할 수 없다고 가정해 보세요.그럼 어쩌지?

구현을 시도해보세요 PDKBF2 와 더불어 최대 라운드 수 귀하의 환경/애플리케이션/사용자 인식이 허용될 수 있습니다.제가 추천하는 가장 낮은 숫자는 2500발입니다.또한 꼭 이용해 보세요. hash_hmac() 작업을 재현하기 어렵게 만드는 것이 가능한 경우.

미래의 관행

PHP 5.5에서는 전체 비밀번호 보호 라이브러리 이는 bcrypt 작업의 모든 고통을 추상화합니다.우리 대부분은 가장 일반적인 환경, 특히 공유 호스트에서 PHP 5.2 및 5.3을 사용하고 있지만 @ircmaxell은 호환성 레이어 PHP 5.3.7과 역호환되는 향후 API를 위해.

암호화 요약 및 면책조항

실제로 필요한 컴퓨팅 성능 금이 가다 해시된 비밀번호가 존재하지 않습니다.컴퓨터가 암호를 "해독"하는 유일한 방법은 암호를 다시 만들고 보안에 사용되는 해싱 알고리즘을 시뮬레이션하는 것입니다.해시의 속도는 무차별 공격 능력과 선형적으로 관련되어 있습니다.더 나쁜 것은 대부분의 해시 알고리즘을 쉽게 병렬화하여 더 빠르게 수행할 수 있다는 것입니다.이것이 바로 bcrypt 및 scrypt와 같은 비용이 많이 드는 체계가 중요한 이유입니다.

모든 위협이나 공격 경로를 예측할 수는 없으므로 사용자를 보호하기 위해 최선을 다해야 합니다. 앞쪽에.그렇지 않으면 공격을 받았다는 사실조차 너무 늦을 때까지 놓칠 수도 있으니... 그리고 당신은 책임이 있습니다.그런 상황을 피하려면 처음부터 편집증적인 행동을 하십시오.자신의 소프트웨어를 (내부적으로) 공격하고 사용자 자격 증명을 도용하거나 다른 사용자의 계정을 수정하거나 해당 데이터에 액세스하려고 시도합니다.시스템의 보안을 테스트하지 않으면 자신 외에는 누구도 비난할 수 없습니다.

마지막으로:나는 암호학자가 아닙니다.내가 말한 것은 모두 내 의견이지만, 상식에 근거한 것이라고 생각합니다 ...그리고 많은 독서.가능한 한 편집증을 갖고 침입하기 어렵게 만든 다음, 여전히 걱정된다면 화이트 해커나 암호 해독가에게 연락하여 코드/시스템에 대해 어떻게 말하는지 확인하십시오.

다른 팁

훨씬 짧고 안전한 대답 - 자신의 암호 메커니즘을 전혀 쓰지 마십시오, 시도 된 테스트 메커니즘을 사용하십시오.

  • PHP 5.5 이상 : password_hash () 좋은 품질과 PHP 코어의 일부입니다.
  • 구형 PHP 버전 : OpenWall 's phpass 라이브러리는 대부분의 사용자 정의 코드보다 훨씬 낫습니다 - WordPress, Drupal 등에 사용됩니다.

대부분의 프로그래머는 취약점을 도입하지 않고 암호화 관련 코드를 안전하게 작성할 수있는 전문 지식이 없습니다.

빠른 자기 테스트 : 비밀번호 스트레칭이란 무엇이며 얼마나 많은 반복을 사용해야합니까? 답을 모르는 경우 사용해야합니다. password_hash(), 암호 스트레칭은 이제 훨씬 빠른 CPU와 사용으로 인한 비밀번호 메커니즘의 중요한 기능입니다. GPUS 및 FPGA 비밀번호를 속도로 깨뜨립니다 초당 수십억 개의 추측 (GPU와 함께).

예를 들어, 당신은 할 수 있습니다 6 시간 안에 8 자 화스터 Windows 암호를 모두 깨뜨립니다 5 개의 데스크탑 PC에 설치된 25 개의 GPU를 사용합니다. 이것은 무차별적인 즉석을 열거하고 확인합니다 매 8 자 Windows 비밀번호, 특수 캐릭터를 포함하여 사전 공격이 아닙니다. 2018 년 현재 2012 년 현재 GPU를 적게 사용하거나 25 GPU로 더 빨리 균열을 일으킬 수있었습니다.

일반 CPU에서 실행되고 매우 빠른 Windows 암호에 대한 무지개 테이블 공격도 많이 있습니다. 이 모든 것이 Windows 때문입니다 아직 소금이나 스트레칭이 아닙니다 암호, Windows 10에서도 - Microsoft와 같은 실수를하지 마십시오!

또한보십시오:

  • 훌륭한 대답 이유에 대한 자세한 내용 password_hash() 또는 phpass 가는 가장 좋은 방법입니다.
  • 좋은 블로그 기사 BCRYPT, SCRYPT 및 PBKDF2를 포함한 주요 알고리즘에 대한 권장 관리 '작업 요소'(반복 수)를 제공합니다.

시스템은 사용중인 해시 알고리즘 중 가장 약한 것만 큼 약한 두 가지 방식으로 비밀번호 해시를 저장하지 않을 것입니다.

PHP 5.5 기준으로 PHP는 해싱 및 암호 확인에 대한 간단하고 안전한 기능을 갖추고 있습니다. password_hash () 그리고 password_verify ()

$password = 'anna';
$hash = password_hash($password, PASSWORD_DEFAULT);
$expensiveHash = password_hash($password, PASSWORD_DEFAULT, array('cost' => 20));

password_verify('anna', $hash); //Returns true
password_verify('anna', $expensiveHash); //Also returns true
password_verify('elsa', $hash); //Returns false

언제 password_hash() 사용되면 무작위 소금을 생성하고 출력 해시에 포함시킵니다 (사용 된 비용 및 알고리즘과 함께). password_verify() 그런 다음 해시를 읽고 사용한 소금 및 암호화 방법을 읽고 제공된 일반 텍스트 비밀번호에 대해 확인합니다.

제공 PASSWORD_DEFAULT PHP는 설치된 PHP 버전의 기본 해싱 알고리즘을 사용하도록 지시합니다. 정확히 어떤 알고리즘을 의미하는지는 미래 버전에서 시간이 지남에 따라 변경되므로 항상 사용 가능한 가장 강력한 알고리즘 중 하나가 될 것입니다.

비용 증가 (기본값 10으로 10으로) 해시는 무차별 대적을 더 어렵게 만들뿐만 아니라 해시를 생성하고 암호를 확인하는 것이 서버의 CPU에 더 많은 작업이 될 것임을 의미합니다.

기본 해싱 알고리즘이 변경 될 수 있지만 사용 된 알고리즘이 해시에 저장되어 있기 때문에 오래된 해시는 계속 잘 확인됩니다. password_verify() 그것에 픽업합니다.

질문에 대한 답변이 있었지만, 해싱에 사용되는 소금은 임의적이어야하며 첫 번째 답변에서 제안 된대로 이메일 주소와는 다르지 않아야한다고 반복하고 싶습니다.

더 많은 설명을 사용할 수 있습니다. http://www.pivotalsecurity.com/blog/password-hashing-salt-it-be-random/

최근에 나는 무작위 비트로 소금에 절인 암호 해시가 추측 할 수 있거나 알려진 소금으로 소금에 절인 것보다 더 안전한 지 논의했습니다. 보자 : 비밀번호를 저장하는 시스템과 임의의 소금을 저장하는 시스템뿐만 아니라 손상된 경우, 공격자는 소금뿐만 아니라 소금에 액세스 할 수 있으므로 소금이 무작위인지 아닌지는 중요하지 않습니다. 공격자는 사전 계산 된 무지개 테이블을 생성하여 해시를 깨뜨릴 수 있습니다. 여기에 흥미로운 부분이 있습니다. 사전 컴퓨팅 테이블을 생성하는 것은 그렇게 사소하지 않습니다. WPA 보안 모델의 예를 들어 보겠습니다. WPA 비밀번호는 실제로 무선 액세스 포인트로 전송되지 않습니다. 대신 SSID (네트워크 이름- Linksys, Dlink 등)와 함께 해시됩니다. 이것이 어떻게 작동하는지에 대한 아주 좋은 설명이 여기에 있습니다. 해시에서 암호를 검색하려면 Salt (네트워크 이름)뿐만 아니라 비밀번호를 알아야합니다. Wi-Fi 교회는 이미 상위 1000 개의 SSID와 약 1 백만 개의 암호를 가진 해시 테이블을 미리 컴퓨팅했습니다. 모든 테이블의 크기는 약 40GB입니다. 귀하의 사이트에서 읽을 수 있듯이 누군가는 15 개의 FGPA 어레이를 3 일 동안 사용하여 이러한 테이블을 생성했습니다. 피해자가 SSID를 "A387CSF3"로 사용하고 암호를 "123456"으로 사용하고 있다고 가정하면 해당 테이블에 의해 갈라질까요? 아니! .. 그럴 순 없어. 암호가 약하더라도 테이블에는 SSID A387CSF3 용 해시가 없습니다. 이것은 임의의 소금을 먹는 아름다움입니다. 그것은 미리 컴퓨터 테이블에 번성하는 크래커를 방해 할 것입니다. 결정된 해커를 멈출 수 있습니까? 아마 그렇지 않을 것입니다. 그러나 임의의 소금을 사용하면 추가 방어 층이 제공됩니다. 우리 가이 주제에 참여하는 동안, 별도의 시스템에 임의의 소금을 저장한다는 추가 이점에 대해 논의합시다. 시나리오 #1 : 암호 해시는 시스템 X에 저장되며 해싱에 사용되는 소금 값은 시스템 Y에 저장됩니다. 이러한 소금 값은 추측 가능하거나 알려진 (예 : 사용자 이름) 시나리오 #2 : 암호 해시는 시스템 X 및 소금 값에 사용 된 소금 값에 저장됩니다. 해싱은 시스템 Y에 저장됩니다.이 소금 값은 무작위입니다. 시스템 X가 손상된 경우, 추측 할 수 있듯이 별도의 시스템에서 임의의 소금을 사용하면 큰 이점이 있습니다 (시나리오 #2). 공격자는 해시를 깨뜨릴 수 있도록 추가 값을 추측해야합니다. 32 비트 소금을 사용하는 경우 각 비밀번호에 대해 2^32 = 4,294,967,296 (약 42 억) 반복이 필요할 수 있습니다.

PHP 5.5에 포함된다는 점을 지적하고 싶습니다. 암호 해싱 API 그것은 래퍼를 제공합니다 crypt(). 이 API는 암호 해시를 확인하고 재 해싱하는 해싱 작업을 크게 단순화합니다. 저자는 또한 a 호환성 팩 (단순한 password.php 파일 형식으로 간단히 require PHP 5.3.7 이상을 사용하는 사람들을 위해 사용하고 지금 당장 사용하려는 사람들을 위해.

현재 BCRYPT 만 지원하지만 다른 암호 해싱 기술을 포함하도록 쉽게 확장되는 것을 목표로하며 기술과 비용이 해시의 일부로 저장되므로 선호하는 해당 기술/비용의 변경 사항은 현재 해시를 무효화하지 않습니다. 프레임 워크. 자동으로, 검증 할 때 올바른 기술/비용을 사용합니다. 또한 자신의 것을 명시 적으로 정의하지 않으면 "안전한"소금을 생성하는 것을 처리합니다.

API는 네 가지 기능을 노출시킵니다.

  • password_get_info() - 주어진 해시에 대한 정보를 반환합니다
  • password_hash() - 암호 해시를 만듭니다
  • password_needs_rehash() - 주어진 해시가 주어진 옵션과 일치하는지 확인합니다. 해시가 현재 기술/비용 체계를 준수하는지 확인하는 데 유용하여 필요한 경우 다시 해쉬 할 수 있습니다.
  • password_verify() - 암호가 해시와 일치하는지 확인합니다

현재 이러한 함수는 암호 _bcrypt 및 password_default 암호 상수를 받아들입니다. 현재 동의어 인 비밀번호는 "새로운 PHP 릴리스에서 변경 될 수 있습니다." 로그인에서 (및 필요한 경우 재활) password_default 및 password_needs_rehash ()를 사용하면 해시가 작업이 거의 없거나 전혀없는 무차별 적 공격에 합리적으로 탄력적이지 않도록해야합니다.

편집 : 방금 Robert K의 답변에 간단히 언급되어 있음을 깨달았습니다. 나는 그것이 어떻게 작동하는지에 대한 약간의 정보를 제공하고 보안을 모르는 사람들에게 제공하는 방법에 대한 조금 더 많은 정보를 제공한다고 생각하기 때문에 여기에 답장을 남겨 둘 것입니다.

사용 중입니다 phpass 거의 모든 PHP 프로젝트에서 매우 쉽게 구현할 수있는 간단한 1 파일 PHP 클래스입니다. 또한보십시오 h.

기본적으로 Phpass에서 구현 된 가장 강력한 사용 가능한 암호화를 사용했습니다. bcrypt WordPress와 같은 프레임 워크에 대한 후진 호환성을 제공하기 위해 MD5로 다른 암호화로 돌아갑니다.

반환 된 해시는 데이터베이스에 저장 될 수 있습니다. 해시 생성을위한 샘플 사용은 다음과 같습니다.

$t_hasher = new PasswordHash(8, FALSE);
$hash = $t_hasher->HashPassword($password);

비밀번호를 확인하려면 다음을 사용할 수 있습니다.

$t_hasher = new PasswordHash(8, FALSE);
$check = $t_hasher->CheckPassword($password, $hash);

기억해야 할 것들

PHP의 비밀번호 암호화에 대해 많은 이야기가 나왔습니다. 대부분은 매우 좋은 조언이지만, 비밀번호 암호화에 PHP를 사용하는 프로세스를 시작하기 전에 다음과 같은 구현 또는 구현 준비가되어 있는지 확인하십시오.

섬기는 사람

포트

PHP와 DB를 실행하는 서버를 제대로 보호하지 않으면 암호화가 아무리 좋은지에 관계없이 모든 노력은 무가치합니다. 대부분의 서버는 비교적 동일한 방식으로 기능하며 포트가 할당되어있어 FTP 또는 쉘을 통해 원격으로 액세스 할 수 있습니다. 원격 연결이 활성화 된 기본 포트를 변경해야합니다. 이 작업을 수행하지 않으면 사실상 공격자가 시스템에 액세스하는 데 한 단계 덜 한 단계를 겪게되었습니다.

사용자 이름

세계에서 좋은 모든 것에 대해 사용자 이름 관리자, 루트 또는 유사한 것을 사용하지 마십시오. 또한 UNIX 기반 시스템에있는 경우 루트 계정 로그인에 액세스 할 수없는 경우 항상 Sudo 만 사용해야합니다.

비밀번호

해킹을 피하기 위해 사용자에게 좋은 비밀번호를 만들라고 말하고 똑같이하십시오. 백도어가 넓게 열릴 때 정문을 잠그려는 모든 노력을 겪는 요점은 무엇입니까?

데이터 베이스

섬기는 사람

이상적으로는 별도의 서버에서 DB와 응용 프로그램을 원합니다. 비용으로 인해 항상 가능하지는 않지만 공격자가 시스템에 완전히 액세스하기 위해 두 단계를 거쳐야하므로 약간의 안전을 허용합니다.

사용자

항상 응용 프로그램에 DB에 액세스 할 수있는 자체 계정이 있으며 필요한 권한 만 제공하십시오.

그런 다음 서버의 어느 곳에도 저장되지 않은 별도의 사용자 계정을 사용하십시오.

항상이 뿌리 나 비슷한 것을 만들지 마십시오.

비밀번호

모든 우수한 비밀번호와 동일한 지침을 따르십시오. 또한 동일한 시스템의 모든 서버 또는 DB 계정에서 동일한 비밀번호를 재사용하지 마십시오.

PHP

비밀번호

DB에 암호를 저장하지 말고 해시와 고유 한 소금을 보관하십시오. 나중에 이유를 설명하겠습니다.

해싱

한 가지 방법 해싱 !!!!!!!, 반전 할 수있는 방식으로 암호를 해시하지 마십시오. 해시는 한 가지 방법이어야합니다. 즉, 반전을 역전시키지 않고 비밀번호를 비교하지 않으면 입력 된 비밀번호를 해시합니다. 같은 방식으로 두 해시를 비교하십시오. 이것은 공격자가 DB에 액세스하더라도 실제로 암호가 무엇인지 알지 못하고 결과 해시만을 의미합니다. 이는 최악의 시나리오에서 사용자에게 더 많은 보안을 의미합니다.

거기에는 좋은 해싱 기능이 많이 있습니다 (password_hash, hash, 등 ...) 그러나 해시가 효과적이기 위해서는 좋은 알고리즘을 선택해야합니다. (bcrypt와 그것과 유사한 것은 괜찮은 알고리즘입니다.)

해싱 속도가 핵심 일 때, 속도가 느리면 무차별 인력 공격에 대한 저항력이 느리게됩니다.

해싱에서 가장 일반적인 실수 중 하나는 해시가 사용자에게 고유하지 않다는 것입니다. 이것은 주로 소금이 고유하게 생성되지 않기 때문입니다.

소금

암호는 항상 해시 전에 소금에 절인 것입니다. Salting은 비밀번호에 임의의 문자열을 추가하여 DB에서 유사한 암호가 동일하게 나타나지 않습니다. 그러나 소금이 각 사용자마다 고유하지 않은 경우 (즉, 하드 코드 소금을 사용) 소금이 소금을 무가치하게 만들었습니다. 일단 공격자가 하나의 암호 소금을 알아 내기 때문에 그는 모두 소금을 가지고 있습니다.

소금을 만들면 소금에 고유 한 비밀번호에 고유한지 확인한 다음 완성 된 해시와 소금을 DB에 저장하십시오. 이것이 할 일은 공격자가 접근을 얻기 전에 각 소금과 해시를 개별적으로 깨뜨려 야하도록 만드는 것입니다. 이것은 공격자에게 더 많은 작업과 시간을 의미합니다.

비밀번호를 만드는 사용자

사용자가 프론트 엔드를 통해 비밀번호를 생성하는 경우 서버로 보내야합니다. 이는 암호화되지 않은 암호가 서버로 전송되고 공격자가 PHP의 모든 보안이 무가치하다는 것을 듣고 액세스 할 수있는 경우 보안 문제가 열립니다. 항상 데이터를 단단히 전송하십시오. 이것은 SSL을 통해 수행되지만 SSL조차도 완벽하지 않습니다 (OpenSSL의 심장마다 결함이 그 예입니다).

또한 사용자가 보안 비밀번호를 만들 수있게하고 간단하며 항상 완료해야합니다. 사용자는 결국에 감사 할 것입니다.

마지막으로, 보안 조치에 관계없이 아무것도 취하지 않더라도 100% 안전하지는 않습니다. 그러나 이러한 단계를 따르면 공격자가 공격자가 더 안전하고 바람직하지 않습니다.

다음은 암호를 쉽게 해시와 소금을 만드는 PHP 클래스입니다.

http://git.io/msjqpw

Google은 SHA256이 PHP에서 사용할 수 있다고 말합니다.

당신은 확실히 소금을 사용해야합니다. 임의 바이트를 사용하는 것이 좋습니다 (캐릭터와 숫자로 제한하지 마십시오). 일반적으로, 더 오래 선택할수록 더 안전하고 느리게됩니다. 64 바이트는 괜찮을 것입니다.

이 문제에 대한 완벽한 주제를 찾았습니다. https://crackstation.net/hashing-security.htm, 나는 당신이 그것으로부터 혜택을 받기를 원했습니다. 여기에 시간 기반 공격에 대한 예방을 제공하는 소스 코드도 있습니다.

<?php
/*
 * Password hashing with PBKDF2.
 * Author: havoc AT defuse.ca
 * www: https://defuse.ca/php-pbkdf2.htm
 */

// These constants may be changed without breaking existing hashes.
define("PBKDF2_HASH_ALGORITHM", "sha256");
define("PBKDF2_ITERATIONS", 1000);
define("PBKDF2_SALT_BYTES", 24);
define("PBKDF2_HASH_BYTES", 24);

define("HASH_SECTIONS", 4);
define("HASH_ALGORITHM_INDEX", 0);
define("HASH_ITERATION_INDEX", 1);
define("HASH_SALT_INDEX", 2);
define("HASH_PBKDF2_INDEX", 3);

function create_hash($password)
{
    // format: algorithm:iterations:salt:hash
    $salt = base64_encode(mcrypt_create_iv(PBKDF2_SALT_BYTES, MCRYPT_DEV_URANDOM));
    return PBKDF2_HASH_ALGORITHM . ":" . PBKDF2_ITERATIONS . ":" .  $salt . ":" . 
        base64_encode(pbkdf2(
            PBKDF2_HASH_ALGORITHM,
            $password,
            $salt,
            PBKDF2_ITERATIONS,
            PBKDF2_HASH_BYTES,
            true
        ));
}

function validate_password($password, $good_hash)
{
    $params = explode(":", $good_hash);
    if(count($params) < HASH_SECTIONS)
       return false; 
    $pbkdf2 = base64_decode($params[HASH_PBKDF2_INDEX]);
    return slow_equals(
        $pbkdf2,
        pbkdf2(
            $params[HASH_ALGORITHM_INDEX],
            $password,
            $params[HASH_SALT_INDEX],
            (int)$params[HASH_ITERATION_INDEX],
            strlen($pbkdf2),
            true
        )
    );
}

// Compares two strings $a and $b in length-constant time.
function slow_equals($a, $b)
{
    $diff = strlen($a) ^ strlen($b);
    for($i = 0; $i < strlen($a) && $i < strlen($b); $i++)
    {
        $diff |= ord($a[$i]) ^ ord($b[$i]);
    }
    return $diff === 0; 
}

/*
 * PBKDF2 key derivation function as defined by RSA's PKCS #5: https://www.ietf.org/rfc/rfc2898.txt
 * $algorithm - The hash algorithm to use. Recommended: SHA256
 * $password - The password.
 * $salt - A salt that is unique to the password.
 * $count - Iteration count. Higher is better, but slower. Recommended: At least 1000.
 * $key_length - The length of the derived key in bytes.
 * $raw_output - If true, the key is returned in raw binary format. Hex encoded otherwise.
 * Returns: A $key_length-byte key derived from the password and salt.
 *
 * Test vectors can be found here: https://www.ietf.org/rfc/rfc6070.txt
 *
 * This implementation of PBKDF2 was originally created by https://defuse.ca
 * With improvements by http://www.variations-of-shadow.com
 */
function pbkdf2($algorithm, $password, $salt, $count, $key_length, $raw_output = false)
{
    $algorithm = strtolower($algorithm);
    if(!in_array($algorithm, hash_algos(), true))
        die('PBKDF2 ERROR: Invalid hash algorithm.');
    if($count <= 0 || $key_length <= 0)
        die('PBKDF2 ERROR: Invalid parameters.');

    $hash_length = strlen(hash($algorithm, "", true));
    $block_count = ceil($key_length / $hash_length);

    $output = "";
    for($i = 1; $i <= $block_count; $i++) {
        // $i encoded as 4 bytes, big endian.
        $last = $salt . pack("N", $i);
        // first iteration
        $last = $xorsum = hash_hmac($algorithm, $last, $password, true);
        // perform the other $count - 1 iterations
        for ($j = 1; $j < $count; $j++) {
            $xorsum ^= ($last = hash_hmac($algorithm, $last, $password, true));
        }
        $output .= $xorsum;
    }

    if($raw_output)
        return substr($output, 0, $key_length);
    else
        return bin2hex(substr($output, 0, $key_length));
}
?>

결국, 수학적으로 이중 호슈팅은 이점을 제공하지 않습니다. 그러나 실제로는 레인보우 테이블 기반 공격을 방지하는 데 유용합니다. 다시 말해, 소금으로 해싱하는 것보다 더 많은 이점이 없으며, 응용 프로그램이나 서버에서 프로세서 시간이 훨씬 적습니다.

나는 보통 사용자 ID (또는 다른 사용자 별 정보)와 함께 SHA1과 SALT를 사용하며 때로는 일정한 소금을 추가로 사용합니다 (따라서 소금에 2 개의 부분이 있습니다).

SHA1은 이제 다소 타협 된 것으로 간주되지만 MD5보다 훨씬 적은 수준입니다. 소금 (모든 소금)을 사용하면 일반적인 사용을 막을 수 있습니다. 무지개 테이블 해시를 공격하기 위해 (일부 사람들은 해시를 검색하여 Google을 일종의 무지개 테이블로 사용했습니다). 공격자는 소금을 사용하여 무지개 테이블을 생성 할 수 있으므로 사용자 별 소금을 포함해야합니다. 그렇게하면 시스템 전체가 아니라 시스템의 모든 레코드에 대해 무지개 테이블을 생성해야합니다! 이러한 유형의 소금을 사용하면 MD5조차도 괜찮습니다.

Sha1 그리고 소금은 충분해야합니다 (자연스럽게, 당신이 무언가를 코딩하고 있는지에 따라 포트 녹스 또는 쇼핑 목록의 로그인 시스템)) 가까운 미래를위한. SHA1이 충분하지 않으면 사용하십시오 SHA256.

소금에 대한 아이디어는 해싱 결과를 균형에서 벗어나는 것입니다. 예를 들어, 빈 문자열의 MD5 하시는 d41d8cd98f00b204e9800998ecf8427e. 따라서 메모리가 충분하다면 해시가 그 해시를보고 그것이 빈 줄의 해시라는 것을 알게 될 것입니다. 그러나 끈이 소금에 절인 경우 (문자열로 예 : "MY_PERSONAL_SALT"), '빈 문자열'의 해시 (예 :MY_PERSONAL_SALT")가된다 aeac2612626724592271634fb14d3ea6, 따라서, 역가지는 불가능합니다. 내가 말하려는 것은 사용하는 것이 낫다는 것을 어느 소금. 따라서 아는 것은 너무 중요하지 않습니다. 어느 사용할 소금.

실제로 있습니다 이것을하는 웹 사이트 - 당신은 그것을 (MD5) 해시에 먹이를 줄 수 있으며, 특정 해시를 생성하는 알려진 일반 텍스트를 뱉어냅니다. 평범한 MD5 하시를 저장하는 데이터베이스에 액세스 할 경우 관리자가 해당 서비스를 위해 해시를 입력하고 로그인하는 것이 사소한 일입니다. 그러나 암호가 소금에 절인 경우 그러한 서비스가 될 것입니다. 효과적인.

또한, 이중 청소는 일반적으로 결과 공간을 줄이기 때문에 나쁜 방법으로 간주됩니다. 모든 인기있는 해시는 고정 길이입니다. 따라서이 고정 길이의 유한 값 만 가질 수 있으며 결과는 덜 다양 해집니다. 이것 ~할 수 있었다 다른 형태의 소금으로 간주되지만 나는 그것을 추천하지 않을 것입니다.

좋아, 더 딱딱한 곳에는 소금 소금이 독특해야하므로 생성하자

   /**
     * Generating string
     * @param $size
     * @return string
     */
    function Uniwur_string($size){
        $text = md5(uniqid(rand(), TRUE));
        RETURN substr($text, 0, $size);
    }

또한 SHA512를 사용하는 해시가 필요하며 PHP에 있습니다.

   /**
     * Hashing string
     * @param $string
     * @return string
     */
    function hash($string){
        return hash('sha512', $string);
    }

이제이 기능을 사용하여 안전한 비밀번호를 생성 할 수 있습니다.

// generating unique password
$password = Uniwur_string(20); // or you can add manual password
// generating 32 character salt
$salt = Uniwur_string(32);
// now we can manipulate this informations

// hashin salt for safe
$hash_salt = hash($salt);
// hashing password
$hash_psw = hash($password.$hash_salt);

이제 데이터베이스를 $ hash_psw 변수 값과 $ 소금 변수에 저장해야합니다.

그리고 승인을 위해 우리는 동일한 단계를 사용합니다 ...

고객 비밀번호를 안전하게 보호하는 가장 좋은 방법입니다 ...

추신 마지막 2 단계의 경우 자신의 알고리즘을 사용할 수 있지만 사용자를 승인해야 할 때 미래 에이 해시 비밀번호를 생성 할 수 있는지 확인하십시오 ...

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