'비밀번호 == XXXXXXX 인 경우'보안 수준이 충분합니까?


20

보안 위험이 중간 이하인 앱 (즉, 뱅킹 앱이 아닌 다른 앱)에 대한 로그인을 만들면 다음과 같이 말함으로써 사용자가 입력 한 비밀번호를 확인할 수 있습니다.

if(enteredPassword == verifiedPassword)
     SendToRestrictedArea();
else
     DisplayPasswordUnknownMessage();

효과가있는 것처럼 보이지만 그것이 필요한 전부라면 확실하지 않습니다. 사용자 이름 / 암호 콤보를 간단하게 검사하면 충분합니까?

업데이트 : 특정 프로젝트는 웹 서비스가되며, 검증은 전적으로 서버 측이며 오픈 소스가 아닙니다. 도메인이 처리 방법을 변경합니까?


3
validPassword의 출처에 따라 다릅니다. 하드 코딩 된 경우 코드를 변경하지 않고 비밀번호를 구성 / 변경할 수 없습니다. 구성 파일에서 가져온 경우 해당 파일에 액세스하는 모든 사람이 볼 수 있습니다.
Alb

1
"사용자 이름 / 암호 콤보를 확인하는 것이 충분합니까?"
Chris

3
@ opinion : 이것이 로그인이 아닌 것보다 나쁜 것 같지 않습니다. 그러한 강력한 주장에 대한 추론을 제공해주십시오.
Morgan Herlocker

1
비밀번호를 비교할 때 비밀번호를 비교할 때 유효하지 않은 용어가 잘못되었습니다. 차이점을 이해하려면 시간을 내십시오.
billy.bob

1
이는 일반 텍스트 비밀번호 저장을 의미하며 이는 무책임합니다. 또한 암호가 잘못되었음을 사용자에게 경고하여 잠재적 인 공격자에게 너무 많은 정보를 제공합니다. "로그인 또는 비밀번호가 잘못되었습니다"와 같이 항상 모호해야합니다.
Rein Henrichs

답변:


26

SSL 없이는 안 됨

암호가 일반 텍스트로 네트워크를 통해 전송되는 경우 안전하지 않습니다. 암호가 네트워크를 통해 일반 텍스트로 전송되는 경우 서버 측의 암호 해시도 안전하지 않습니다.

HTML <input type="password"/>태그는 내용을 일반 텍스트로 보내므로 웹 사이트에서 SSL을 사용하여 비밀번호를 전송하지 않으면 서버에 비밀번호를 저장하는 방법에 관계없이 문제가됩니다.

(비밀번호를 요청하는 대화 상자가 브라우저에 표시되는 HTTP 인증은 서버와 브라우저의 공통 인증 메커니즘에 따라 일반 텍스트 일 ​​수도 있고 그렇지 않을 수도 있습니다. 따라서이를 사용하지 않고이를 피할 수 있습니다. SSL)

사이트 관리자가 의심되는 경우

이제 HTTPS를 사용하여 웹 사이트를 수행한다고 가정하면 사이트 관리자 (일반 텍스트 암호를 읽을 수있는 사용자) 및 시스템에 액세스 할 수있는 다른 사용자가 올바르게 작동하도록한다면이 정보가 안전 할 수 있습니다. 이제는 그들이 관리하고 있기 때문에 그들이 당신의 웹 사이트에서 원하는 것을 할 수 있다는 것이 명백 할 것입니다, 그러나 그들이 암호를 읽을 수 있다면, 다른 사람들의 사이트에서 도난당한 로그인 / 암호 쌍을 사용할 수도 있습니다.

관리자로부터 암호를 안전하게 유지하는 방법

비밀번호를 저장하고 확인하는 한 가지 안전한 방법은 다음과 같습니다.

def change_password user, new_password
  salt = random(65536).to_s(16) #will be 4 characters long
  password_hash = salt + hash(salt + new_password)
  store(user,password_hash)
end

def does_password_match? user, entered_password
  correct_password_hash = retrieve(user)
  salt = correct_password_hash[0...4]
  entered_password_hash = salt + hash(salt + entered_password)
  return correct_password_hash == entered_password_hash
end

해시 함수의 경우 강하고 강력한 레인보우 테이블이없는 것을 사용하십시오. 무지개 테이블 주위에서 필요한 경우 소금의 길이를 변경할 수 있습니다.

현재 환경, 네트워크 대기 시간의 변동성 및 사용자 이름을 공개적으로 알려야 hash('0000'+entered_password)하는지 여부에 따라 사용자가 존재하지 않는 경우 다른 코드 경로를 계산 하여 공격자가 암호가 잘못되었다고 판단하는 데 걸리는 시간에 따라 유효한 사용자 이름 결정


1
좋은 조언 :) SSL과 관련하여 우리는 wild에서 작동하는 것을 디자인하고 비대칭 암호화를 사용하여 암호를 인코딩 한 다음 (Javascript 필요) 서버에서 암호를 해독해야했습니다. 그러면 salt + hash가 정상적으로 발생합니다. 또한 공개 키는 웹 페이지와 함께 전송되므로 임의로 변경할 수 있습니다.
Matthieu M.

1
@Matthieu M .: 누군가 웹 페이지를 위조 할 수있는 경우 공개 키를 해당 개인 키를 알고있는 공개 키로 변경할 수도 있습니다. 따라서 귀하의 아이디어는 수동 읽기 공격에만 도움이되고 중간자에 대해서는 도움이되지 않습니다.
Paŭlo Ebermann

@Paulo : 예, SSL은 암호화뿐만 아니라 인증서에 대해서도 동의합니다. 불행히도 여기서 샷을 호출하지 않으며 사람들이 웹 페이지를 정기적으로 http://연결 하고 싶다고 말하면 실망합니다. /
Matthieu M.

@Matthieu : 공개 웹 페이지의 일부로 public_key를 전송 encrypt(entered_password, public_key)하고 클라이언트에서 컴퓨팅 하고 그 결과를 서버로 전송한다는 의미 does_password_match?(user, decrypt(encrypted_password, private_key))입니까?
Ken Bloom

@Ken : 어느 정도, 당신은 암호화 권리를 얻었다. 암호 does_password_match(user, salt, decrypt(encrypted, key))는 사용자에 따라 소금과 더 일치합니다 . 내가 말했듯이, 명백한 문제는 중간자 보호가 부족하다는 것입니다.
Matthieu M.

52

즉, 보안 수준이 낮은 시나리오에서도 암호를 공개 텍스트로 유지하는 것이 좋습니다.

당신은 오히려해야합니다 :

if(hash(enteredPassword) == storedHash)

MD5와 같이 간단한 해시를 사용할 수 있습니다


22
비밀번호 해시 +1 그러나 나는 적어도 소금도 조금 추가 할 것입니다. 그렇지 않으면 사용자가 시스템간에 사용자 이름과 암호를 재사용하기 때문에 보안 수준이 낮은 앱을 위반하면 공격자가 훨씬 높은 보안 앱을 위반할 수 있습니다. 예를 들어, 최근 HBGary 해킹은 보안 수준이 낮은 CMS 시스템이 해시에 소금을 추가하지 않았기 때문에 웹 사이트를 실행하는 CMS 시스템을 손상시키고 서버에 대한 루트 액세스로 부분적으로 전환했습니다. news / 2011 / 02 /…
Justin Cave

1
동의 ... 다음 사항을 고려하십시오. "문자열 JavaFile.class | grep -i 암호"
Bill

암호를 한 번만 사용하는 경우 일반 텍스트로 암호를 사용하면 어떤 문제가 발생합니까?

10
사용자 비밀번호를 한 번만 사용 하지 않기 때문에 @Tim . 연구에 따르면 사용자는 비밀번호를 여러 번 사용 하지 않더라도 비밀번호를 여러 번 재사용하는 것으로 나타났습니다 (예 : register.co.uk/2011/02/10/password_re_use_study ).
Scott

3
@Tim : 텍스트 편집기에서 exe, dll 등을 열면 암호가 표시 될 수 있습니다.
거스 카 발칸 티

14

해싱을 제안하는 사람들과 동의하지만 여기에서 다시 발명 할 바퀴가 있습니다. 플랫폼에 따라 너무 많은 개입 없이도 모든 사용자 관리 항목을 안전하고 안전하게 다루는 역할 / 사용자 관리 도구를 찾을 수 있습니다.


방금 ASP.Net 멤버십 제공 업체를 발견했지만 "이런 시간을 낭비하는 데 몇 번이나 시간을 낭비 했습니까?"라고 생각하고있었습니다.
glenatron

8

특히 사용자의 불편과 정보의 안전을 보장하는 균형이 필요하기 때문에 보안은 매우 중요합니다. 일반적으로 필요한 보안 수준은 데이터의 중요성에 따라 결정됩니다. 한마디로 :

isSecuritySufficient = effortToBreak > rewardForBreaking

나쁜 일을하는 사람들에 대한 일반적인 오해는 그들이 따르는 것입니다. 그들 중 대부분은 신뢰 를 파괴하려고 합니다 . 사용자의 신뢰를 보호하기 위해 항상 최선을 다해야합니다. 그것의 일부는 그들의 신분 이 안전 하도록하기 위해 당신의 실사를하고 있습니다. 그들은 저장하는 데이터에 대해서는 관심이 적지 만 가장 낮은 보안 임계 값 일지라도 자신의 신원에 대해서는 관심이 있습니다.

사용 가능한 여러 가지 저비용 (구현 및 사용자에게 미치는 영향) 옵션이 있습니다. 그중 하나는 최소한 비밀번호를 해시하는 것입니다. 비밀번호처럼 민감한 것을 일반 텍스트로 저장하는 모든 서비스는 해킹 당혹스러워 할 가치가 있습니다.

비밀번호 보호를위한 일반 원칙

  • 비밀번호를 일반 텍스트로 저장 하지 마십시오
  • SHA-1 또는 SHA-512와 같은 보안 해시 기능을 사용하는 해시 (MD5조차도 일치하는 해시를 찾기가 너무 쉽습니다)
  • 응용 솔트 값을 사용하십시오. 솔트는 추측하기 어렵게하기 위해 암호에 추가 된 임의의 바이트입니다. 솔트는 런타임에 생성되고 머신에 대한 정보를 어떤 식 으로든 저장 및 참조하기보다는 시드 값으로 사용해야합니다.
  • 사용자 별 소금 값을 사용하십시오. 이것을 어플리케이션 솔트와 함께 사용하십시오.
  • 네트워크를 통과하는 모든 인증 요청을 암호화 하십시오. 이는 웹 애플리케이션에 SSL을 사용함을 의미합니다.

인증에 SSL을 사용하므로 최소한 사용자 계정을 다루는 모든 페이지를 암호화해야합니다. 이를 통해 최대한 많은 사용자 ID를 보호 할 수 있습니다.

비밀번호 관리에 대한 참고 사항 : 사용자는 때때로 비밀번호를 잊어 버립니다. 절대 최악의 당신이 할 수있는 일이 이메일로 그들에게 자신의 암호를 보내는 것입니다. 위에서 설명한 원칙을 구현하면 어쨌든 그렇게 할 수 없습니다. 등록 된 이메일 주소로 전송 된 링크를 사용하여 비밀번호를 재설정하는 방법을 제공하는 것이 훨씬 좋습니다. 해당 재설정 링크에는 페이지에 액세스하는 사람이 본인임을 확인할 수있는 일회용 코드가 있습니다.


1
처음에 나는 애플리케이션 솔트 + 사용자 솔트에 대한 아이디어에 정말 놀랐다. 예를 들어, 응용 소금의 4 문자와 사용자 소금의 4 문자를 사용한 경우, 사용자 소금의 8 문자와 8 문자의 차이는 소금의 절반이 모든 사용자에 대해 동일하다는 것입니다. 응용 소금이 아닌 사용자 소금의 크기를 늘리는 것이 더 안전 할 것 같습니다. 또한 애플리케이션 솔트가 하드웨어를 기반으로하는 경우 모든 비밀번호를 무효화하지 않으면 하드웨어를 업그레이드하거나 변경할 수 없습니다.
David Conrad

문제는 사용자 소금이 사용자 비밀번호와 함께 데이터베이스 행에 포함된다는 것입니다. 나쁜 사람이 소금의 용도를 알고 데이터베이스에서 볼 수 있다면 소금을 완전히 해독하는 방법을 알고 있습니다. 저장되는 대신 계산되는 부분을 응용 프로그램에 포함시킴으로써 (사용자가 생각할 때마다 같은 방식으로) 사용자 테이블을 크랙하기가 훨씬 어려워집니다. 물론 한 걸음 더 나아가서 1 개의 순수한 무작위 소금과 1 개의 계산 된 소금을 사용자별로 지정할 수 있습니다.
Berin Loritsch

아, 알다시피, 소금의 일부를 데이터베이스에 보관하지 마십시오. 말이 되네요 감사합니다.
David Conrad

행마다 고유 한 한 행당 소금을 저장하는 데 문제가 없습니다. 해시는 "fd84235a55bbfeb1585a3dd069d48127989c9753058b51b6ba2056fd6c5a0a91"(SHA256)입니다. 소금은 "671254bdf7944f8fa88e6c9913b948ee"입니다. 비밀번호를 얻을 수 있다고 생각하십니까? 그 소금에 대한 무지개 테이블이 없습니다 (소금이 주어 졌더라도), 당신은 그것을 강제로 붙였습니다.
Bryan Boettcher

3

암호를 다른 용도로 사용하지 않으면 좋습니다. 사용자가 비밀번호를 재사용 할 수 있다고 결정하는 위험이 여전히 있으므로 다음과 같이하면 더 좋습니다.

if(hash(enteredPassword) == hashOfValidPassword)

자신이나 암호가 일반 텍스트로 저장되어 있다는 것을 알고있는 사람을위한 것이라면 괜찮습니다.


1
vartec의 답변에 대한 Justin Cave의 의견에서와 같이 소금을 사용 if (hash (enteredPassword + salt) == hashOfValidSaltedPassword)하십시오 +. 이것은 아마도 레인보우 테이블의 사용을 방해합니다. 레인보우 테이블은 암호가 가능한 해시 테이블입니다.
David Thornley

확인하려는 모든 것이 해시 인 경우 저장된 해시와 동일한 해시를 생성 할 때까지 가능한 문자열 루프를 통과 할 수 없었습니까? 결국 동일한 해시에 해당하는 많은 문자열이 있습니다.
Morgan Herlocker

@Prof Plum : 해싱 알고리즘이 좋은 경우 충돌을 찾기가 매우 어렵습니다. 이것은 현대 암호화의 기초입니다. 본질적으로 단방향 기능입니다.

3

소스 코드가 있습니까? 그렇지 않더라도 바이너리를 사용할 수있는 경우 컴퓨터 지침에서 암호를 찾을 수 있다고 확신합니다. 체크섬을 수행하고 대신 비교하는 것이 좋습니다.

보안이 중요하지 않더라도 보안을 간과하지 마십시오.


2
예, 오픈 소스 프로젝트 인 경우 나쁜 생각 :)

소스를 갖는 것이 차이를 만든다고 생각하면 보안에 대해서는 아무것도 모릅니다.
mattnz

1

절대적으로하지. 의 읽고 , 해커가 보안 웹 사이트를 해킹하는 방법에 대해 설명합니다. 당신은 체인에서 가장 약한 고리로 당신을 계획 할 것입니다.


0

몇 가지 답변에서 암호 자체를 저장하지 말고 해시를 저장해야하며 SSL을 사용해야한다는 점에 주목했습니다.

당신은 말할 수 있습니다, 큰 거래는 무엇입니까? 내 응용 프로그램이 해킹되면 걱정할 필요가 없습니다. 사용자가 모든 사이트에서 동일한 암호를 재사용하는 것은 매우 일반적인 패턴입니다. 해커가 사이트를 해킹하고 사용자의 암호에 액세스 할 수 있었기 때문에 해커는 다른 사이트의 많은 사용자를 해당 사용자에게 더 중요하게 가장 할 수 있습니다. 따라서 해커가 사용자의 은행 정보액세스하는 첫 번째 단계는 사이트 해킹 입니다.

그리고 비밀번호를 해싱하는 것만으로는 충분하지 않습니다. 소금으로 해시해야합니다. 해커는 역 해시 조회 테이블을 가지므로 지정된 해시에 대해 일치하는 비밀번호를 찾을 수 있습니다.

이러한 기능을 구현하지 않기로 선택한 경우 보안이 부족하다는 사실을 사용자에게 알리고 다른 곳에서 사용하는 것과 동일한 암호를 사용하지 않도록 권장해야합니다.


-2

이것이 서버 측 인 한. 그렇습니다.

좀 더 보안을 원한다면 https로 이동하여 DB의 암호를 암호화 / 해시하십시오.


3
이것이 웹앱이라고 생각하는 이유는 무엇입니까?
Chris

좋은 지적! 난 그냥했다.
Morons

4
-1 서버 측이지만 여전히 문제가 없습니다.
GSto
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.