Java에서 보안 정적 로그인 자격 증명 시스템을 어떻게 구현하시겠습니까?

StackOverflow https://stackoverflow.com/questions/103203

문제

최근 보안 감사를 실시한 결과 여기에 있는 시스템의 몇 가지 약점이 드러났습니다.이로 인해 발생하는 작업 중 하나는 파트너 자격 증명 시스템을 업데이트하여 더욱 안전하게 만들어야 한다는 것입니다.

"기존" 방식은 (잘못된) 비밀번호를 생성하고 이를 ID와 함께 파트너에게 제공한 다음 해당 ID와 해당 비밀번호의 Base 64 인코딩 사본을 https를 통한 모든 XML 요청과 함께 보내는 것이었습니다. .그런 다음 이를 디코딩하고 유효성을 검사합니다.

이러한 비밀번호는 변경되지 않으며(그러면 파트너가 비밀번호를 변경하기 위해 코딩/구성을 변경해야 하고 여러 환경에 대해 수백 명의 파트너와 비밀번호 만료를 조정하는 것은 악몽이 될 것이기 때문입니다) 사람이 입력할 필요가 없습니다. 또는 사람이 읽을 수 있습니다.파트너를 위한 더 좋지만 여전히 상대적으로 간단한 구현이 있다면 이를 변경할 수 있습니다.

기본적으로 다음 두 가지로 귀결됩니다.보다 안전한 Java 비밀번호 생성 시스템이 필요하고 안전한 방식으로 전송되도록 보장해야 합니다.

나는 몇 가지 수동 비밀번호 생성기를 찾았지만 이 작업을 수행하는 표준 방법으로 실제로 눈에 띄는 것은 없습니다(아마 그럴 만한 이유가 있을 것입니다).https를 통한 간단한 Base 64 인코딩보다 더 안전하게 전송하는 방법이 있을 수도 있습니다.

비밀번호 생성기에 대해 무엇을 하시겠습니까? 전송 방법이 충분히 안전하다고 생각하십니까?

편집하다:XML은 SOAP 메시지로 제공되며 자격 증명은 XML 자체가 아닌 헤더에 있습니다.또한 비밀번호는 설정할 때 각 파트너에 대한 일회성 작업이므로 생성기의 효율성에 대해 크게 걱정하지 않습니다.

도움이 되었습니까?

해결책

비밀번호 생성

전송용 비밀번호를 인코딩하는 경우 보안을 실제로 추가하는 유일한 인코딩은 암호화입니다.Base-64 또는 16진수를 사용하는 것은 보안을 위한 것이 아니라 단지 XML과 같은 텍스트 형식에 포함할 수 있도록 하기 위한 것입니다.

엔트로피는 비밀번호 품질을 측정하는 데 사용됩니다.따라서 무작위 "동전 뒤집기"로 각 비트를 선택하면 최고 품질의 비밀번호가 제공됩니다.비밀번호가 다른 암호화 키만큼 강력하기를 원하므로 최소 128비트의 엔트로피를 권장합니다.

비밀번호를 텍스트로 인코딩하려는 방법에 따라 두 가지 쉬운 방법이 있습니다(보안 관점에서는 실제로 중요하지 않음).

을 위한 베이스-64, 다음과 같이 사용하십시오.

  SecureRandom rnd = new SecureRandom();
  /* Byte array length is multiple of LCM(log2(64), 8) / 8 = 3. */
  byte[] password = new byte[18];
  rnd.nextBytes(password);
  String encoded = Base64.encode(password);

다음에서는 Base-64 인코더를 사용할 필요가 없습니다.결과 인코딩은 컴팩트하지 않으며(24자가 아닌 26자) 비밀번호의 엔트로피도 많지 않습니다.(그러나 130비트는 이미 많은 숫자로, 인간이 선택한 최소 30자의 비밀번호와 비슷합니다.)

SecureRandom rnd = new SecureRandom();
/* Bit length is multiple of log2(32) = 5. */
String encoded = new BigInteger(130, rnd).toString(32); 

새로운 SecureRandom 객체를 생성하는 것은 계산 비용이 많이 들기 때문에 비밀번호를 자주 생성하려는 경우 하나의 인스턴스를 생성하여 유지하는 것이 좋습니다.

더 나은 접근 방식

XML 자체에 비밀번호를 포함시키는 것은 실수인 것 같습니다.

우선, 보낸 사람이 보내는 문서를 처리하기 전에 보낸 사람을 인증하고 싶은 것 같습니다.내가 당신의 배짱을 싫어하고 서비스 거부 공격을 실행하기 위해 거대한 XML 파일을 보내기 시작한다고 가정해 보겠습니다.내가 합법적인 파트너가 아닌지 확인하기 위해서만 XML을 구문 분석하고 싶습니까?서블릿이 인증되지 않은 사용자의 요청을 미리 거부했다면 더 좋지 않을까요?

둘째, 합법적인 파트너의 비밀번호는 전송 중에 HTTPS로 보호되었지만 이제 비밀번호는 시스템 어딘가에 "일반"으로 저장될 가능성이 높습니다.보안이 좋지 않습니다.

더 나은 접근 방식은 파트너가 HTTP 요청 헤더에 자격 증명이 포함된 문서를 보낼 때 파트너를 인증하는 것입니다.HTTPS만 허용하는 경우 문서에서 비밀번호를 완전히 빼내고 HTTP "기본" 인증 대신 헤더.전송 중에 SSL로 보호되며 시스템에 일반 파일로 저장되지 않습니다(인증 목적으로 단방향 해시만 저장함).

HTTP 기본 인증은 간단하고 널리 지원되며 귀하와 귀하의 파트너가 SSL 클라이언트 인증서보다 구현하기가 훨씬 쉽습니다.

문서 내용 보호

문서 내용 자체가 민감한 경우에는 보낸 사람이 문서를 암호화하고 암호화된 형식으로 저장해야 합니다.이를 수행하는 가장 좋은 방법은 공개 키 암호화를 사용하는 것이지만 이는 다른 질문의 주제가 될 것입니다.

다른 팁

인증에 SSL 키를 사용할 수 없나요?

SSL을 통해(HTTPS를 통해) 비밀번호를 전송하는 것이 감사 팀에서 "안전하지 않은" 것으로 간주되는 이유가 확실하지 않습니다.따라서 두 가지 사항을 요청하면 두 번째 사항(비밀번호가 안전한 방식으로 전송되는지 확인)이 이미 잘 처리되고 있는 것 같습니다.

첫 번째로, 감사 결과 귀하의 비밀번호가 안전하지 않은 것으로 노출된 점을 알아야 합니다...

전체 비밀번호 접근 방식을 포기하고 양면 인증 SSL 연결을 허용하는 클라이언트 인증서를 사용하기 시작했습니다.

각 클라이언트에 대해 개별 인증서를 생성하고 서명해야 합니다.SSL 핸드셰이크에서는 클라이언트의 인증서를 요청하고 확인합니다.실패하면 연결은 401 상태 코드로 종료됩니다.

인증서는 언제든지 취소될 수 있으므로 이전 고객의 연결을 쉽게 끊을 수 있습니다.

이 모든 것은 통신 전 핸드셰이크에서 발생하므로 서버에 데이터가 넘쳐나는 것은 불가능합니다.

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