Loading...
본문 바로가기
👥
총 방문자
📖
0개 이상
총 포스팅
🧑
오늘 방문자 수
📅
0일째
블로그 운영

여러분의 방문을 환영해요! 🎉

다양한 개발 지식을 쉽고 재미있게 알려드리는 블로그가 될게요. 함께 성장해요! 😊

CS

[보안] 비밀번호 평문으로 보내는 것은 상관 없을까?

by 꽁이꽁설꽁돌 2025. 7. 31.
728x90
반응형
     

목차

     

     

     

     

    client side

    클라이언트의 입장에서 평문을 보낼 때는 적법한 사용자 외에 악성코드, 바이러스 등으로 클라이언트의 정보가 노출되고 있다고 가정하겠습니다.

    이 경우는 해시를 하거나 암호화를 하는 것으로 사용자의 패스워드가 노출 되는 것을 막을 수 없습니다. 혹시, 이미 바이러스에 감염이 되어있었다면 HTTPS 인증서를 통해 도메인에 대한 유효성을 검증하거나 다른 방식의 보안 솔루션을 도입해야합니다.

     

     

    중간자

    (중간자는 client-server의 단대단 사이에서 해킹을 통해 통신 패킷을 도청 혹은 조작하는 있는 해커를 의미합니다.)

     

    중간자가 통신 패킷을 볼 수 있다고 하더라도 HTTPS로 패킷이 암호화 되어있기 때문에 유의미한 정보를 얻을 수는 없습니다.

    만약 어떤 방법을 통해 열어 볼 수 있다고 가정한다면, 단순히 패스워드를 해시/암호화 하는 것으로는 재사용 공격(Replay Attack)으로부터 보호할 수 없습니다.

     

     

    서버

    서버 입장에서는 패스워드가 평문일 경우 길이/중복문자/사전단어/영문자+숫자+특수문자의 조합/등등의 유효성을 검사할 수 있다는 장점이 있습니다.

    클라이언트가 유효성 검사 후에 해싱하여 보내준다면, 서버는 클라이언트가 유효성 검사를 조작 후에 해시하여 보내줬는지를 파악할 수가 없습니다.

    구글링을 통해 몇몇 블로그, 홈페이지들을 찾아본 결과 HTTPS를 통해 암호를 전송할때 해시/암호화 등의 조치를 한번 더 취하는 것이 사이트 보안 이점을 얻기 어렵다는 글들을 보았습니다. 왜냐하면 공격자가 해시/암호화된 패스워드를 획득하였을 때 서버가 두 경우의 차이를 알 수 없기 때문입니다.(→ 만약, 이 문제(Challenge-Response)에 대한 조치가 취해졌다면 해시/암호화 하는 것과 하지 않는 것의 차이는 없습니다.)

     

    유일한 이점은 사용자가 여러 사이트에서 동일한 패스워드를 사용하고 있을 때 사용자를 보호한다는 것입니다.(이것이 사이트를 더 안전하게 만들지는 못합니다.)

     

     

    challenge-response란?

    ex) OTP, 2FA, 하드웨어 키

     

    서버와 클라이언트 간에 연결되어 있는지에 대한 여부를 판단하는 인증을 위해 사용되는 인증 메커니즘

     

    1. 클라이언트 인증 - 서버가 자신과 통신하기 위해 네트워크로 연결되어 있는 클라이언트를 인증하는 방법

    2. 서버 인증 - 클라이언트가 자신과 통신하려는 서버를 인증하는 방법

    3. 클라이언트-서버 상호인증 - 양쪽에서 서로를 인증하는 방법

     

    클라이언트 인증의 경우 서버가 cahllenge를 생성해서 클라이언트로 보내고, 클라이언트는 이 값을 자신이 가지고 있는

    키로 암호화를 해서 응답 메세지에 첨부해서 서버에게 보낸다. 서버는 응답메시지를 복호화 해서 자신이 보냈던  challenge인지 

    비교를 하고, 동일한 값이라면 인증성공으로, 다른 값이라면 인증실패로 처리한다. 서버 인증의 경우 클라이언트 인증과 반대로 처리되며, 클라이언트-서버 상호인증의 경우 양쪽에서 동일한 처리를 하게 된다.

     

     

    구체적인 예: 비대칭 서명 방식 (ECDSA, RSA 등)

    1. 클라이언트가 받은 challenge: abc123

    signature1 = sign('abc123', privateKey);
     

    2. 다음번 로그인 때 challenge: xyz789

    signature2 = sign('xyz789', samePrivateKey);

     

    signature1 !== signature2

    → 둘 다 같은 private key로 서명했지만, 서명 대상이 다르기 때문에 결과도 다름

     

    서버는 어떻게 검증하냐?

    서버는 클라이언트의 **공개키(public key)**를 알고 있으므로:

    verify('abc123', signature1, publicKey) // → true verify('xyz789', signature2, publicKey) // → true

     

    만약 공격자가 아무 키나 쓰거나, 아무 값이나 보내면:

    verify('xyz789', signatureFake, publicKey) // → false

     

     

    그런데 challenge가 달라지면 무슨 이점이 있을까?

    재사용 공격을 방지할 수 있는 이점이 있다.

     

     

    • 서버는 "nonce=xyz456" 같은 무작위 값을 매번 새로 보냄
    • 클라이언트는 매번 그 nonce에 대해 새로운 응답 생성
    • **이전 응답(signature, hash 등)**은 다음 요청에서 절대 사용할 수 없음
    • 공격자가 복붙해도 "이건 내가 준 문제에 대한 답 x" → 실패 "

     

     

    Replay Attack

    공격자가 이전에 통신에서 **가로챈 응답(signature, hash 등)**을 저장해뒀다가,

    그걸 나중에 다시 서버에 그대로 보내서 인증을 통과하려는 공격입니다.

     

     

     

    반응형