대부분의 사이트에서 HTTPS를 통해 서버에 일반 텍스트로 암호를 보내는 것으로 나타났습니다. 그 대신 암호의 해시를 서버에 보낸다면 어떤 이점이 있습니까? 더 안전할까요?
대부분의 사이트에서 HTTPS를 통해 서버에 일반 텍스트로 암호를 보내는 것으로 나타났습니다. 그 대신 암호의 해시를 서버에 보낸다면 어떤 이점이 있습니까? 더 안전할까요?
답변:
이것은 오래된 질문이지만이 중요한 문제에 대한 내 의견을 제공 할 필요성을 느꼈습니다. 여기에 잘못된 정보가 너무 많아
OP는 HTTP를 통해 명확하게 암호를 보내는 것을 언급하지 않았습니다. HTTPS 만 사용했지만 많은 사람들이 어떤 이유로 HTTP를 통해 암호를 보내는 문제에 응답하는 것 같습니다. 즉,
암호는 일반 텍스트로 저장 (전송은 고사)해서는 안된다고 생각합니다. 이는 디스크 나 메모리에 보관되지 않음을 의미합니다.
여기에 응답하는 사람들은 HTTPS가 은색 총알이라고 생각하는 것 같습니다. 그러나 확실히 큰 도움이되며 인증 된 세션에서 사용해야합니다.
원래 암호가 무엇인지 알 필요가 없습니다. 필요한 것은 사용자가 선택한 원본 텍스트를 기반으로 인증 "키"를 생성 (및 안정적으로 다시 생성)하는 신뢰할 수있는 방법입니다. 이상적인 세계에서이 텍스트는 돌이킬 수없는 솔트를 사용하여 해싱하여 즉시 "키"를 생성해야합니다. 이 솔트는 생성되는 사용자 자격 증명에 고유해야합니다. 이 "키"는 시스템이 암호로 사용하는 것입니다. 이렇게하면 향후 시스템이 손상 될 경우 이러한 자격 증명은 자신의 조직에 대해서만 유용하며 사용자가 게으르고 동일한 암호를 사용하는 다른 곳에서는 사용할 수 없습니다.
그래서 우리는 열쇠가 있습니다. 이제 클라이언트 장치의 암호 흔적을 정리해야합니다.
다음으로 시스템에 해당 키를 가져와야합니다. "일반적으로"키 또는 암호를 전송해서는 안됩니다. HTTPS를 통해서도 아닙니다. HTTPS는 뚫을 수 없습니다. 실제로 많은 조직이 공격 관점이 아니라 트래픽 검사를 수행하여 자체 보안 정책을 구현하는 신뢰할 수있는 MITM이 될 수 있습니다. 이것은 HTTPS를 약화시키고 이것이 발생하는 유일한 방법은 아닙니다 (예 : HTTP MITM 공격으로 리디렉션). 안전하다고 생각하지 마십시오.
이 문제를 해결하기 위해 임시 임시 값으로 키를 해시합니다. 이 임시 값은 시스템에 키를 제출할 때마다 고유합니다. 여러 번 전송해야하는 경우 동일한 세션 동안 동일한 자격 증명에 대해서도 마찬가지입니다. 이 임시 값이 자체 시스템에 도착하면이를 되돌려 인증 키를 복구하고 요청을 인증 할 수 있습니다.
이 시점에서 나는 그것을 당신의 시스템에 영구적으로 저장하기 전에 마지막으로 한 번 해시 할 것입니다. 이렇게하면 SSO 등의 목적으로 파트너 조직과 자격 증명의 솔트를 공유 할 수 있으며, 동시에 자신의 조직이 사용자를 가장 할 수 없음을 증명할 수 있습니다. 이 접근 방식의 가장 좋은 부분은 사용자의 승인 없이는 사용자가 생성 한 것을 공유하지 않는다는 것입니다.
내가 공개 한 것보다 더 많은 것이 있기 때문에 더 많은 연구를 수행하십시오. 그러나 사용자에게 진정한 보안을 제공하고 싶다면이 방법이 현재 가장 완벽한 대응이라고 생각합니다.
TL; DR :
HTTPS를 사용하십시오. 암호마다 고유 한 솔트를 사용하여 암호를 되돌릴 수 없도록 안전하게 해시합니다. 클라이언트에서이 작업을 수행하십시오. 실제 암호를 전송하지 마십시오. 사용자의 원래 암호를 서버로 전송하는 것은 "OK"또는 "Fine"이 아닙니다. 원래 암호의 흔적을 정리하십시오. HTTP / HTTPS에 관계없이 임시 값을 사용하십시오 . 여러 수준에서 훨씬 더 안전합니다. (OP에 대한 답변).
HTTPS를 사용하므로 해싱없이 비밀번호를 보내는 것이 좋습니다 (HTTPS를 통해 일반 텍스트가 아님). 또한 애플리케이션이 콘텐츠의 보안을 유지하기 위해 HTTPS에 의존하는 경우 HTTPS를 통해 전송하기 전에 암호를 해시하는 것은 쓸모가 없습니다.
아니요, 사실 이것은 취약점이 될 것입니다. 공격자가 데이터베이스에서 해시를 얻을 수 있으면이를 크래킹 할 필요없이이를 사용하여 인증 할 수 있습니다. 어떠한 상황에서도 사용자 나 공격자가 해시 암호를 얻을 수 없어야합니다.
암호 해싱의 요점은 보안 계층을 추가하는 것입니다. 공격자가 SQL 주입 또는 안전하지 않은 백업을 사용하여 데이터베이스에서 해시와 솔트를 얻을 수 있다면 무차별 대입을 통해 일반 텍스트를 찾아야합니다. John The Ripper 는 일반적으로 솔트 된 암호 해시를 해독하는 데 사용됩니다.
https를 사용하지 않는 것은 OWASP Top 10 : A9-Insufficient Transport Layer Protection 위반입니다.
편집 :
구현에서 a를 계산 한 sha256(client_salt+plain_text_password)
다음 서버 측에서 다른 해시를 계산 sha256(server_salt+client_hash)
하면 심각한 취약점이 아닙니다. 그러나 여전히 요청을 도청하고 재생하기 쉽습니다. 따라서 이것은 여전히 WASP A9의 명백한 위반입니다. 그러나 이것은 여전히 메시지 다이제스트를 보안 계층으로 사용하고 있습니다.
https에 대한 클라이언트 측 교체에서 가장 가까운 것은 javascript의 키 교환에서 diffie-hellman입니다 . 그러나 이것은 활성 MITM 공격을 방지하므로 기술적으로 OWASP A9를 위반하는 것입니다. 코드 작성자는 이것이 HTTPS를 완전히 대체하지는 않는다는 데 동의하지만,없는 것보다 낫고 클라이언트 측 해싱 시스템보다 낫습니다.
해시를 유선으로 전송하면 해시의 목적이 완전히 무효화됩니다. 공격자가 해시를 전송하고 암호를 잊어 버릴 수 있기 때문입니다. 요컨대, 일반 텍스트에서 해시를 사용하여 이해하는 시스템은 넓게 열려 있으며 네트워크 스니핑 이상으로 손상 될 수 있습니다.
일반 텍스트의 암호는 절대로 클라이언트를 떠나지 않습니다 (HTTPS를 사용하는 경우도 아님). 서버가 실제 암호를 알 필요가 없기 때문에 클라이언트를 떠나기 전에 비가 역적으로 해시되어야합니다.
해싱 후 전송은 여러 위치에서 동일한 암호를 사용하는 게으른 사용자의 보안 문제를 해결합니다 (나는 알고 있습니다). 그러나 이것은 해커가 해시를 전송하고 서버가 수락하도록 할 수 있기 때문에 데이터베이스에 대한 액세스 권한을 얻은 해커 (또는 다른 방법으로 해시를 손에 넣을 수있는 해커)로서 애플리케이션을 보호하지 않습니다.
이 문제를 해결하기 위해 서버가 수신하는 해시를 해시하고 하루에 호출 할 수 있습니다.
내가 만들고있는 소켓 기반 웹 애플리케이션의 문제에 대한 나의 접근 방식은 클라이언트에 연결할 때 서버가 솔트 (해싱 전에 추가 할 임의의 문자열)를 생성하고이를 소켓 변수에 저장 한 다음이 해시를 전송하는 것입니다. 클라이언트에게. 클라이언트는 사용자 암호를 가져 와서 해시하고 서버에서 솔트를 추가하고 모든 것을 해시 한 후 서버로 전송합니다. 그런 다음이 해시를 해시 (DB의 해시 + 솔트)와 비교하는 서버로 전송됩니다. 내가 아는 한 이것은 좋은 접근 방식이지만 공정하게 말하면 주제에 대해 많이 읽지 않았으며 내가 잘못하면 수정하고 싶습니다. :)
HTTP Digest 사용-http를 통해서도 비밀번호를 보호합니다 (하지만 가장 좋은 사용법은 https를 통한 http digest입니다).
Wikipedia :
HTTP 다이제스트 액세스 인증은 웹 서버가 웹 사용자와 자격 증명을 협상하는 데 사용할 수있는 합의 된 방법 중 하나입니다 (HTTP 프로토콜 사용). 다이제스트 인증은 기본 액세스 인증의 암호화되지 않은 사용을 대체하여 네트워크를 통해 일반 텍스트로 암호를 보내지 않고도 사용자 ID를 안전하게 설정할 수 있도록합니다. 다이제스트 인증은 기본적으로 암호화 분석을 방지하기 위해 nonce 값을 사용하는 MD5 암호화 해싱 응용 프로그램입니다.
링크 : http://en.wikipedia.org/wiki/Digest_access_authentication
"실제"사용을 보려면 http 다이제스트 인증을 사용하는 php openid 공급자 인 phpMyID를 참조하십시오. http://siege.org/phpmyid.php 참조하십시오.
.. 또는 php 인증 샘플에서 시작할 수 있습니다. http://php.net/manual/en/features.http-auth.php
HTTP 다이제스트 rfc : http://www.faqs.org/rfcs/rfc2617
내 테스트에서 모든 최신 브라우저가 지원합니다 ...
HTTPS를 통한 일반 텍스트 암호를 HTTP를 통한 해시 된 암호로 바꾸려는 경우 문제가 발생합니다. HTTPS는 통신 채널을 열 때 임의의 공유 트랜잭션 키를 생성합니다. (상대적으로) 단기 트랜잭션에 사용되는 공유 키를 강제로 강제하는 데 거의 제한되어 있기 때문에 크래킹하기가 어렵습니다. 당신의 해시는 단지 스니핑되고, 오프라인으로 취해 져서 무지개 테이블에서 찾아 보거나, 오랜 시간에 걸쳐 강제로 강제 될 수있는 반면에.
그러나 HTTPS를 통해 전송 된 기본 클라이언트 측 암호 난독 화 (해시 아님)에는 약간의 가치가 있습니다. 내가 착각하지 않는다면이 기술은 실제로 일부 은행에서 사용됩니다. 이 기술의 목적은 암호가 유선을 통해 스니핑되지 않도록 보호하는 것이 아닙니다. 그보다는 그들이 보는 모든 HTTPS GET / POST 요청을 가져 오는 멍청한 스파이 도구와 브라우저 플러그인에 암호를 사용할 수 없도록하는 것입니다. 사용자 세션에서 캡처 된 400MB의 무작위 GET / POST 트랜잭션 인 악성 웹 사이트에서 캡처 된 로그 파일을 보았습니다. HTTPS 만 사용하는 웹 사이트는 로그에 일반 텍스트 비밀번호로 표시되지만 매우 기본적인 난독 화 (ROT13)를 사용하는 웹 사이트도 즉시 사용되지 않는 비밀번호로 표시 될 수 있습니다.
https 서버에 연결되어있는 경우 서버와 브라우저 간의 데이터 스트림을 암호화해야합니다. 데이터는 전송되기 전과 수신 된 후에 만 일반 텍스트입니다. Wikipedia 기사
면책 조항 : 저는 보안 전문가가 아니며 희망을 가지고 게시하고 있습니다. 다른 사람이 지나치게 신중하거나 개선 가능한 나의 위치를 비판하고 나는 그것을 배울 것입니다. 즉, 클라이언트를 떠날 때 해싱이 데이터베이스에 넣기 전에 백엔드에서 해시 할 필요가 없다는 것을 의미하지는 않는다는 점을 강조하고 싶습니다.
둘 다
다음과 같은 이유로 두 가지를 모두 수행하십시오.
주행 중 해싱은 SSL 연결이 손상 되어도 원시 암호를 볼 수없는 전송 취약점을 해결하는 데 도움이됩니다. 승인 된 사용자를 가장 할 수 있다는 점은 중요하지 않지만 사용자가 이메일과 관련하여 비밀번호를 읽지 못하도록 보호합니다. 대부분의 사람들은 모범 사례를 따르지 않고 많은 계정에 동일한 암호를 사용하므로 방문자에게 심각한 취약점이 될 수 있습니다.
누군가가 어떻게 든 데이터베이스에서 암호를 읽을 수 있다면 (이런 일이 발생합니다. SQL 삽입이라고 생각합니다) 내 API를 통해 사용자를 가장하는 권한있는 작업을 실행할 수 없습니다. 이것은 해시 비대칭 때문입니다. DB에 저장된 해시를 알고 있어도 생성에 사용 된 원래 키를 알지 못하며 이것이 인증 미들웨어가 인증에 사용하는 것입니다. 이것은 또한 항상 해시 저장소를 소금에 넣어야하는 이유이기도합니다.
물론, 데이터베이스에서 원하는 내용을 읽을 수있는 자유가 있다면 다른 많은 피해를 입힐 수 있습니다.
여기서 강조하고 싶은 것은 클라이언트에서 출발하기 전에 키를 해시하기로 결정했다면 그것만으로는 충분하지 않습니다. 백엔드 해싱은 훨씬 더 중요합니다. 그러면 password
필드 의 내용을 볼 수 있습니다. 해시 든 일반 텍스트 든 상관 없습니다. 인증 된 클라이언트를 가장하기 위해 그대로 복사 할 수 있습니다. (@ user3299591이 설명하는 단계를 따르지 않는 한, 권장합니다). 반면에 DB 열을 해싱하는 것은 필수이며 구현하기가 전혀 어렵지 않습니다.
SSL / TLS가 nonce를 대체하지 않습니까? SSL / TLS는 또한 재생 공격으로부터 보호하기 때문에 이것의 부가가치를 보지 못했습니다.
암호를 해시하고 암호화되지 않은 채널을 통해 보내는 것은 실제로 덜 안전합니다. 클라이언트에서 해싱 알고리즘을 노출합니다. 해커는 암호의 해시를 스니핑 한 다음 나중에이를 사용하여 해킹 할 수 있습니다.
HTTPS를 사용하면 HTTPS가 암호화 된 두 채널을 사용하기 때문에 해커가 단일 소스에서 암호를 얻지 못하도록 할 수 있습니다.
이점이 있는지 여부와 보안 수준이 더 높거나 낮은 지 여부는 실제로 구현에 달려 있습니다. 틀림없이 몇 가지 이점이 있지만 제대로 구현하지 않으면 일반 텍스트 암호조차 전달하는 것보다 덜 안전한 솔루션을 만들 수 있습니다.
이는 네트워크 트래픽에 대한 액세스 권한과 데이터베이스에 대한 액세스 권한의 두 가지 유형의 공격의 관점에서 볼 수 있습니다.
공격자가 네트워크 트래픽의 일반 텍스트 버전을 가로 챌 수있는 경우 암호 해시를 보는 것이 일반 텍스트로 보는 것보다 더 안전합니다. 공격자는 여전히 해당 해시를 사용하여 서버에 로그인 할 수 있지만 다른 시스템에서 유용 할 수있는 암호를 확인하려면 해당 해시의 무차별 대입 크랙 (때로는 미리 계산 됨)이 필요합니다. 사람들은 다른 시스템에서 다른 암호를 사용해야하지만 종종 사용하지 않습니다.
공격자가 아마도 백업 복사본을 통해 데이터베이스에 대한 액세스 권한을 얻은 경우 해당 정보만으로는 로그인 할 수 없도록해야합니다. 예를 들어, 로그인 이름으로 솔트 된 해시를로 저장하고 hash(login_name+password)
직접 비교를 위해 클라이언트에서 동일한 해시를 전달한 경우 공격자는 무작위로 사용자를 선택하고 데이터베이스에서 읽은 해시를 전송하여 다음으로 로그인 할 수 있습니다. 해당 사용자가 암호를 모르면 위반 범위가 증가합니다. 이 경우 공격자가 로그인하기 위해 일반 텍스트를 알아야하므로 일반 텍스트로 암호를 보내는 것이 더 안전 할 수 있습니다. 이것이 구현이 핵심입니다. 일반 텍스트 암호를 보내든 해당 암호의 클라이언트 측 해시를 보내든 서버 측에서 해당 값을 해시하고 해당 해시를 사용자 레코드에 저장된 해시와 비교해야합니다.
명심해야 할 개념 :