이 기사는 PHP에서 해시 기능을 이해하고 올바르게 적용하려는 개발자를위한 것입니다. 우리는 MD5와 SHA-1을 비교하여 PHP의 원칙, 출력, 충돌 저항, 속도, 전형적인 용도 및 실제 사용으로부터 명확하고 실용적인 제안을 제공하고, 더 안전한 대안 및 사용 예방 조치를 설명 할 것입니다.
해시 (해시) 함수 : 길이의 입력을 수락하고 출력 고정 길이의 "요약"을 출력합니다. 종종 데이터 무결성을 검증하고, 서명 기준을 생성하며, 인덱스를 만드는 데 사용됩니다.
돌이킬 수없는 : 해시 함수는 일방적이어야합니다. 이론적으로 원래의 입력은 요약에서 추론 할 수 없습니다 (그러나 공격자의 능력에 따라 절대적으로는 아님).
충돌 : 다른 입력이 동일한 출력을 생성하는 경우. 이상적인 해시는 충돌을 찾기가 어렵습니다.
출력 길이
MD5 : 128 비트, 일반적으로 32 자 육각형 ( D41D8CD98F00B204E98998ECF8427E )으로 표현됩니다.
SHA-1 : 160 비트, 일반적으로 40 자 16 진로 표현됩니다 (예 : DA39A3EE5E6B4B0D3255BFEF95601890AFD80709 ).
보안 (초록)
MD5 : 실용적이고 실행 가능한 충돌 공격이 입증되었으며 보안에 민감한 시나리오 (서명, 인증서, 비밀번호 스토리지 등)에서 사용할 수 없습니다.
SHA-1 : MD5보다 강하지 만 경험적으로 금이 간 (충돌을 찾기위한 연구/실험적 증거)은 점차 안전한 해시로 감가 상각되었다.
속도
MD5는 일반적으로 SHA -1보다 빠르지 만 (내부 상태가 짧고 계산량이 적음), 속도 차이는 현대 하드웨어의 주요 고려 사항이 아닙니다. 보안이 더 중요합니다.
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-string">"hello world"</span></span><span>;
</span><span><span class="hljs-comment">// MD5</span></span><span>
</span><span><span class="hljs-variable">$md5</span></span><span> = </span><span><span class="hljs-title function_ invoke__">md5</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>); </span><span><span class="hljs-comment">// 32 hex</span></span><span>
</span><span><span class="hljs-variable">$md5_raw</span></span><span> = </span><span><span class="hljs-title function_ invoke__">md5</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>, </span><span><span class="hljs-literal">true</span></span><span>); </span><span><span class="hljs-comment">// 원래 바이너리 16 바이트</span></span><span>
</span><span><span class="hljs-comment">// SHA-1</span></span><span>
</span><span><span class="hljs-variable">$sha1</span></span><span> = </span><span><span class="hljs-title function_ invoke__">sha1</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>); </span><span><span class="hljs-comment">// 40 hex</span></span><span>
</span><span><span class="hljs-variable">$sha1_raw</span></span><span> = </span><span><span class="hljs-title function_ invoke__">sha1</span></span><span>(</span><span><span class="hljs-variable">$data</span></span><span>, </span><span><span class="hljs-literal">true</span></span><span>); </span><span><span class="hljs-comment">// 원래 바이너리 20 바이트</span></span><span>
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"MD5: <span class="hljs-subst">$md5</span></span></span><span>\n";
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"SHA1: <span class="hljs-subst">$sha1</span></span></span><span>\n";
</span></span>키가 필요한 메시지 인증 (보다 안전한 무결성 검증)의 경우 hmac을 사용하십시오.
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$key</span></span><span> = </span><span><span class="hljs-string">"secret-key"</span></span><span>;
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-string">"important payload"</span></span><span>;
</span><span><span class="hljs-comment">// 더 길고 안전한 해시를 사용하는 것이 좋습니다(예:sha256)</span></span><span>
</span><span><span class="hljs-variable">$hmac</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hash_hmac</span></span><span>(</span><span><span class="hljs-string">'sha256'</span></span><span>, </span><span><span class="hljs-variable">$data</span></span><span>, </span><span><span class="hljs-variable">$key</span></span><span>);
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"HMAC-SHA256: <span class="hljs-subst">$hmac</span></span></span><span>\n";
</span></span>비 보안 고유 식별/빠른 검증 만 (작은 위험은 허용됩니다)
MD5 또는 SHA-1은 모두 파일 이름 해시, 간단한 캐시 키 및 중복 제거의 빠른 판단을 생성하는 데 사용될 수 있습니다 (그러나 강력한 일관성 보장으로 의존 할 수는 없습니다).
안전하고 민감한 시나리오에 사용됩니다 (절대 권장되지 않음)
비밀번호 저장, 디지털 서명, TLS/인증서 지문, 서명 검증 등 : MD5/SHA-1을 사용하지 마십시오 . 둘 다 실질적인 충돌 공격 (특히 MD5)을 가지고 있으며 공격자는 동일한 다이제스트에서 다른 메시지를 만들 수 있습니다.
파일 무결성 확인
전송 중 우발적 인 손상을 방지하기 만하면 (비 대회 시나리오) MD5/SHA-1은 여전히 파일 다운로드 페이지에서 일반적입니다. 그러나 악의적 인 변조가 걱정된다면 더 강한 해시 (SHA-256/512) 또는 서명 (HMAC/Public 및 Private Key Signature)을 사용하십시오.
MD5 : 2000 년대 초반부터 여러 충돌 공격과 실제 공격이 있었으며 보안 목적으로 널리 사용되지 않았습니다.
SHA-1 : MD5보다 더 안전한 것으로 간주되었지만 연구 및 실험은 실제 충돌을 보여 주었으므로 (예 : 2017 년 학계가 발표 한 실제 충돌 데모와 같은) 안전 요구 사항이 높은 상황에서는 피해야합니다.
(참고 : 위의 내용은 개요입니다. 공개 된 연구 및 엔지니어링 관행은 두 사람이 충돌에 저항하는 데 충분하지 않음을 보여줍니다.)
암호는 항상 특수 암호 해시 함수를 사용합니다 . password_hash () / password_verify () 사용, php default ( password_default )는 최신 보안 알고리즘 (예 : bcrypt 또는 더 나은 구현)을 사용하고 무작위 소금 및 비용 요소를 자동으로 처리합니다.
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-comment">// 비밀번호 해싱 및 확인(예)</span></span><span>
</span><span><span class="hljs-variable">$password</span></span><span> = </span><span><span class="hljs-string">'user-password'</span></span><span>;
</span><span><span class="hljs-variable">$hash</span></span><span> = </span><span><span class="hljs-title function_ invoke__">password_hash</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, PASSWORD_DEFAULT);
</span><span><span class="hljs-comment">// 저장 $hash 데이터베이스로 이동하십시오</span></span><span>
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">password_verify</span></span><span>(</span><span><span class="hljs-variable">$password</span></span><span>, </span><span><span class="hljs-variable">$hash</span></span><span>)) {
</span><span><span class="hljs-comment">// 검증이 통과되었습니다</span></span><span>
}
</span></span>메시지 무결성 및 인증은 HMAC 또는 서명과 함께 사용됩니다 . 적대적 환경의 경우 hash_hmac () (예 : SHA256 또는 SHA512 )를 사용하거나 공개 키 서명 (OpenSSL_SIGN 등)을 사용하십시오.
<span><span><span class="hljs-meta"><?php</span></span><span>
</span><span><span class="hljs-variable">$tag</span></span><span> = </span><span><span class="hljs-title function_ invoke__">hash_hmac</span></span><span>(</span><span><span class="hljs-string">'sha256'</span></span><span>, </span><span><span class="hljs-variable">$message</span></span><span>, </span><span><span class="hljs-variable">$secret_key</span></span><span>);
</span></span>일반적으로 SHA-2 또는 SHA-3 시리즈는 해시에 대해 선호됩니다 : 예를 들어, SHA256 , SHA512 , HASH ( 'SHA256', $ DATA) 또는 HASH ( 'SHA512', $ DATA)를 통해 PHP에서 사용할 수 있습니다. 이들은 강도에서 MD5/SHA-1보다 훨씬 낫습니다.
이진을보다 효율적으로 처리 해야하는 경우 원래 바이너리 출력 ( MD5 ($ Data, True) / SHA1 ($ Data, True) ) 및 Base64 인코딩 스토리지 또는 결과의 전송을 사용할 수 있습니다.
고유 한 암호 해싱 체계 "Salt + Multiple Hashings를 사용하여"자신만의 암호 해싱 체계를 만들려고하지 마십시오 . 오류는 유지 보수가 발생하기 쉽습니다. 언어/프레임 워크에서 권장하는 암호 해시 API를 사용하십시오.
출력 길이 : MD5 = 128 비트 (32 16 진수), SHA-1 = 160 비트 (40 16 진).
보안 : SHA-1> MD5이지만 더 이상 안전 중요 시나리오에 적합하지 않습니다.
속도 : MD5가 약간 빠르지 만 차이는 선택 기준 (안전 우선 순위)이되어서는 안됩니다.
권장 목적 : 비 안전한 고유 식별 또는 호환 시나리오에만 해당됩니다. 안전한 목적으로 SHA-2/SHA-3/HMAC/Password_hash를 사용하십시오.
새 코드를 작성하고 보안에 관심이있는 경우 MD5 또는 SHA -1을 사용하지 마십시오 . 무결성 및 인증을 위해 HASH ( 'SHA256', $ DATA) / HASH_HMAC ( 'SHA256', $ DATA, $ 키)를 사용하고 암호 를 관리하려면 암호를 관리합니다. 역사적 시스템과 호환되거나 보안과 관련이없는 시나리오에서만 MD5/SHA-1 만 고려하십시오.