2013-05-19 1 views
4

BCrypt의 현재 구현이 올바른지 알고 싶습니다. BCrypt.checkpw()을 사용하지 않아서 문제가 발생할 수 있으므로 여기에서 확인해야합니다.Java : BCrypt를 잘 사용합니까?

Hasher.java 컨테이너 클래스 : 여기

abstract public class Hasher { 
    public static String hash(final char[] input) { 
     String output = Hasher.hash(new String(input)); 
     for (int i = 0; i < input.length; i++) { 
      input[i] = 0; 
     } 
     return output; 
    } 

    public static String hash(final String input) { 
     return BCrypt.hashpw(input, BCrypt.gensalt()); 
    } 
} 

하나의 문제 : JPasswordField 나에게 보안상의 이유로 char[]을 제공하지만 BCrypt.hashpw()에만 문자열을 받아들입니다. 문자열이 내 기억에 떠 다니는 것을 피하려면 어떻게해야합니까?

에서 로깅의 클라이언트 구현 : 그래서 해시가 네트워크를 통해 전송됩니다

String hashedPassword = Hasher.hash(password); 
Network.getInstance().send("login " + username + " " + hashedPassword); 

는 현재 네트워크는 암호화되지 않습니다하지만 난 그 추가에 계획입니다.

계정 생성의 서버 구현 :

public static Account createAccount(final String username, final String password) { 
    String hashedPassword = Hasher.hash(password.toCharArray()); 
    return new Account(username, hashedPassword); 
} 

확인 암호의 서버 구현 :

public boolean checkPassword(final String hashedPassword) { 
    return this.hashedPassword.equals(hashedPassword); 
} 

의 데이터베이스에서 온다 (서버의 메모리에 해시되는 this.hashedPassword으로 부팅). 내 설정의

등록 : 암호가 해시됩니다로 로그인

  • , 클라이언트 상당한 시간이 걸립니다.
  • 계정을 만들거나 암호를 변경하면 서버에서 암호가 해시되므로 상당한 시간이 걸립니다.
  • 로그인 시도의 유효성 검사는 해싱이 필요하지 않으므로 서버를 거의 사용하지 않습니다.
  • 누군가 해시가 포함 된 데이터베이스를 보유하게되면 계정 당 비밀번호를 해독하는 데 상당한 시간이 걸립니다.
  • 나는 여전히 BCrypt.gensalt()에 대한 좋은 업무 요소를 찾아야합니다.

제 가정을 확인해주십시오.

감사합니다.

+0

제공된 암호를 확인하려면 저장된 암호와 동일한 소금으로 암호 해시해야합니다. – Gumbo

+1

소금은 '해시'안에 저장됩니다 (BCrypt 해시는 실제로 해시 그 이상입니다). 검증 부분을 다루지 않습니까? – skiwi

+0

인증 클라이언트 쪽에서 해싱을 수행하는 것은 일반적으로 좋지 않습니다. 한 가지 방법은 누군가 해시 데이터베이스를 사용하여 암호를 해독하지 않은 경우에도 다른 사람으로 로그인 할 수 있습니다. 또한 소금이 해싱 프로세스 중에 무작위로 생성되므로 로그인해도 동일한 해시가 두 번 생성되지 않으므로 서버 측의 해시와 일치하지 않습니다. – Aurand

답변

10

이 설정에는 몇 가지 문제가 있습니다.

1) 소금은 해싱 프로세스 중에 무작위로 생성 된 값이어야합니다 (클라이언트가 저장된 해시 데이터베이스에 액세스 할 수 없기 때문에 클라이언트는 어떤 소금을 사용할 지 알 수 없습니다. 로그인 해시를 만들 때 사용

2)이 구현은 클라이언트가 전달한 비밀번호를 실제로 확인하지 않고 클라이언트가 전달한 비밀번호 해시를 확인합니다. 즉 누군가가 해시 데이터베이스를 얻으면 즉시 해시를 사용하여 로그인 할 수 있습니다. 그런 다음 암호를 확인하지 않기 때문에 암호를 뽑을 필요가 없습니다.

이러한 두 가지 문제는 모두 해시 서버 측을 모두 이동하면 쉽게 해결할 수 있습니다.당신이 언급 한 문제에 대한

업데이트

.

1) 보안 시스템을 만들려는 의도가있는 경우 SSL/TLS를 사용해야합니다. 암호 해시를 일반 텍스트로 보내는 것은 암호를 일반 텍스트로 보내는 것처럼 거의 안전하지 않습니다. 둘 다 끔찍한 생각입니다. HTTPS를 사용하십시오.

2) 서버 측 해싱을 수행하는 것은 꽤 일반적인 관행입니다. 해시 프로세스는 계산적으로 비싸지 만 검색을 비실용적으로 만들지 만 인증 워크 플로를 방해해서는 안됩니다. DoSed에 대해 정말로 염려한다면, 주어진 사용자가 마지막 N 초 동안 로그인을 시도한 횟수를 추적하십시오. 일정 횟수 이상 실패한 경우 계정을 잠급니다.

+0

해싱 서버 측 (두 가지 문제는 해결할 수 없지만 지금까지 실패했는지는 확실하지 않음)은 다음과 같습니다. 1) 네트워크 채널을 통해 암호를 거의 평문으로 보내야하고 2) 이것은 로그인 시도마다 서버에 많은 스트레스를 가할 수 있습니다. 현재 작동중인 경우 설치 프로그램은 로그인 페이지에 초점을 맞춘 DDoS 공격에 대응하는 것이 이상적입니다. – skiwi

+0

업데이트 된 답변보기 – Aurand

+0

+1 좋은 답변입니다. – Steve

관련 문제