모의해킹 스터디 3주차 과제(1) - 로그인 케이스 구현

2024. 11. 1. 03:31·모의해킹/모의해킹 스터디

이번주 과제는

2024.10.31 - [모의해킹/모의해킹 스터디] - 모의해킹 스터디 3주차 정리

 

모의해킹 스터디 3주차 정리

로그인 이란?식별과 인증 작업사용자가 데이터를 입력하면, 데이터와 일치하는 값을 찾아내고 그 값에 해당 사용자가 맞는지 확인하는 작업식별/인증식별이란?수 많은 데이터 중 특정 데이터를

it-techlog.tistory.com

여기서 정리했던 로그인 케이스를 코드로 구현하는 것이다.

개발

먼저 간단한 로그인 화면을 만들어주었다.

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>로그인 페이지</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css">
    <style>
        .text-center { 
            margin-bottom: 30px; 
        }
        .form-group { 
            margin-bottom: 10px; 
        }
        .form-group .form-control { 
            height: 45px; 
        }
        .submit-btn { 
            width: 100%; 
            background-color: #70a2ee; 
            border-color: #c2d7f7; 
        }
    </style>
</head>
<body class="bg-light">
    <?php include '../header.php'; ?> <!-- 헤더 포함 -->
    <main class="container">
        <div class="row justify-content-center" style="height: 100vh;">
            <div class="col-md-4 my-auto">
                <h2 class="text-center">로그인</h2>
                <form method="post" action="각 파일명.php">
                    <div class="form-group">
                        <input type="text" class="form-control" name="id" placeholder="아이디" autocomplete="off">
                    </div>
                    <div class="form-group">
                        <input type="password" class="form-control" name="password" placeholder="비밀번호" autocomplete="current-password">
                    </div>
                    <button type="submit" class="submit-btn btn btn-primary btn-block">로그인</button>
                </form>
            </div>
        </div>
    </main>
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

 

그다음 DB에 다음과 같은 데이터를 삽입해 놓았다.

DB 데이터

 

아래 순서로 진행할 것이며 로그인 페이지의 `action="각 파일명.php"` 에 넣어 해당 코드를 출력해 보려고 한다.

1. 식별과 인증을 동시에 실행(identi_auth_simul.php)
2. 식별과 인증을 분리하여 실행(identi_auth_sep.php)
3. 식별과 해시값을 적용시킨 인증을 동시에 실행(identi_auth_simul_hash.php)
4. 식별과 해시값을 적용시킨 인증을 분리하여 실행(identi_auth_sep_hash.php)

1. 식별과 인증을 동시에 실행

개발(identi_auth_simul.php)

<?php
    require_once 'db_info.php';// 데이터베이스 연결

    $id = $_POST['id'];
    $password = $_POST['password'];

    var_dump($id);
    var_dump($password);

    $sql = "select * from login_test where user_id = ? and user_pw = ?";

    //stmt 세팅
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("ss", $id, $password);
    $stmt->execute();
    $stmt_result = $stmt->get_result();
    $result = $stmt_result->fetch_assoc();

    if($result){
        //로그인 성공
        echo "로그인에 성공하였습니다.";
    }else{
        //로그인 실패
        echo "로그인에 실패하였습니다.";
    }

    $stmt->close(); 
?>

결과

  • 로그인 실패

로그인 실패

  • 로그인 성공

로그인 성공

2. 식별과 인증을 분리하여 실행

개발(identi_auth_sep.php)

<?php
    require_once 'db_info.php';// 데이터베이스 연결

    $id = $_POST['id'];
    $password = $_POST['password'];

    var_dump($id);
    var_dump($password);

    $sql = "select * from login_test where user_id = ?";

    //stmt 세팅
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $id);
    $stmt->execute();
    $stmt_result = $stmt->get_result();
    $result = $stmt_result->fetch_assoc();

    if($result){
        if($result['user_pw'] == $password){
            //로그인 성공
            echo "로그인에 성공하였습니다.";
        }else{
            //로그인 실패
            echo "로그인에 실패하였습니다.";
        }
    }else{
        //로그인 실패
        echo "로그인에 실패하였습니다.";
    }

    $stmt->close(); 
?>

결과

  • 로그인 실패

로그인 실패

  • 로그인 성공

로그인 성공

3. 식별과 해시값을 적용시킨 인증을 동시에 실행

개발(identi_auth_simul_hash.php)

<?php
    require_once 'db_info.php';// 데이터베이스 연결

    $id = $_POST['id'];
    $password = $_POST['password'];
    $hashed_pw = hash('sha256', $password); // 비밀번호 해시 적용

    var_dump($id);
    var_dump('해시값 적용 전 비밀번호 : ' . $password);
    var_dump('해시값 적용 후 비밀번호 : ' . $hashed_pw);

    $sql = "select * from login_test where user_id = ? and user_pw = ?";

    //stmt 세팅
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("ss", $id, $hashed_pw);
    $stmt->execute();
    $stmt_result = $stmt->get_result();
    $result = $stmt_result->fetch_assoc();

    if($result){
        //로그인 성공
        echo "로그인에 성공하였습니다.";
    }else{
        //로그인 실패
        echo "로그인에 실패하였습니다.";
    }

    $stmt->close(); 
?>

결과

  • 로그인 실패

  • 로그인 성공

로그인 성공

4. 식별과 해시값을 적용시킨 인증을 분리하여 실행

개발(identi_auth_sep_hash.php)

<?php
    require_once 'db_info.php';// 데이터베이스 연결

    $id = $_POST['id'];
    $password = $_POST['password'];
    $hashed_pw = hash('sha256', $password); // 비밀번호 해시 적용

    var_dump($id);
    var_dump('해시값 적용 전 비밀번호 : ' . $password);
    var_dump('해시값 적용 후 비밀번호 : ' . $hashed_pw);

    $sql = "select * from login_test where user_id = ?";

    //stmt 세팅
    $stmt = $conn->prepare($sql);
    $stmt->bind_param("s", $id);
    $stmt->execute();
    $stmt_result = $stmt->get_result();
    $result = $stmt_result->fetch_assoc();

    if($result){
        if($result['user_pw'] == $hashed_pw){
            //로그인 성공
            echo "로그인에 성공하였습니다.";
        }else{
            //로그인 실패
            echo "로그인에 실패하였습니다.";
        }
    }else{
        //로그인 실패
        echo "로그인에 실패하였습니다.";
    }

    $stmt->close(); 
?>

결과

  • 로그인 실패

  • 로그인 성공

로그인 성공

후기

다양한 로그인 케이스들을 구현해 봤다.

  • 식별과 인증을 동시에 실행
    • 코드가 아이디와 비밀번호를 동시에 확인할 수 있어 간단하고 직관적이다
    • 비밀번호가 평문으로 데이터베이스에 저장되어 있어 데이터베이스가 해킹당할 경우 모든 비밀번호가 유출되므로 보안이 취약하다. 
  • 식별과 인증을 분리하여 실행
    • 아이디가 존재하는지 먼저 확인한 후 비밀번호를 확인하므로, 관련한 로직을 추가로 개발한다면 로그인 시도가 실패하는 경우의 수를 줄일 수 있다. 
    • 두 개의 로직이 필요하므로 첫 번째 코드보단 성능이 떨어질 수 있다.
  • 식별과 해시값을 적용시킨 인증을 동시에 실행
    • 비밀번호를 해시 알고리즘을 사용하여 저장하므로 데이터베이스가 해킹되더라도 비밀번호가 안전하다.
    • 해시를 사용하여 비밀번호를 비교하므로 보안성이 높다.
    • 비밀번호 해시를 확인하기 위해 아이디와 비밀번호를 동시에 확인해야 하므로, 여전히 SQL 쿼리에서 비밀번호가 노출될 수 있다.
  • 식별과 해시값을 적용시킨 인증을 분리하여 실행
    • 비밀번호를 해시 알고리즘을 사용하여 저장하므로 데이터베이스가 해킹되더라도 비밀번호가 안전하다.
    • 아이디가 존재하는지 먼저 확인한 후 비밀번호를 확인하므로, 관련한 로직을 추가로 개발한다면 로그인 시도가 실패하는 경우의 수를 줄일 수 있다.
    • 해시를 사용하여 비밀번호를 비교하므로 보안성이 높다.
    • 비밀번호를 별도로 비교하기 때문에 해시 된 비밀번호를 비교하는 과정이 추가되어 약간의 성능 저하가 있을 수 있다.
    • 비밀번호 해시를 검증하는 과정이 추가되므로 코드가 다소 복잡해질 수 있다.
  • 결론적으로 네 번째 로직이 개발 시에 가장 안전하고 바람직하며 첫 번째 로직, 두 번째 로직은 해시를 사용하지 않아 보안에 취약하므로 해당 로직처럼 개발하지 않도록 주의해야 한다. 
  • 이번에는 SHA-256 알고리즘을 활용하였으나, bcrypt 및 Argon2와 같은 다양한 해시 알고리즘을 사용하여 개발을 진행하고, 각각의 특징들을 비교해 봐야겠다.
728x90
반응형
저작자표시 비영리 동일조건 (새창열림)

'모의해킹 > 모의해킹 스터디' 카테고리의 다른 글

모의해킹 스터디 4주차 정리  (0) 2024.11.08
모의해킹 스터디 3주차 과제(2) - 리눅스 환경에서 PHP로 JWT 구현  (0) 2024.11.06
모의해킹 스터디 3주차 정리  (0) 2024.10.31
모의해킹 스터디 2주차 과제(2) - 로그인  (0) 2024.10.28
모의해킹 스터디 2주차 과제(1) - 회원가입  (0) 2024.10.27
'모의해킹/모의해킹 스터디' 카테고리의 다른 글
  • 모의해킹 스터디 4주차 정리
  • 모의해킹 스터디 3주차 과제(2) - 리눅스 환경에서 PHP로 JWT 구현
  • 모의해킹 스터디 3주차 정리
  • 모의해킹 스터디 2주차 과제(2) - 로그인
BPM37093
BPM37093
luna의 IT기술 정리
  • BPM37093
    IT Study Log
    BPM37093
  • 링크

  • 글쓰기 관리
    • 분류 전체보기 (43)
      • 모의해킹 (37)
        • 웹해킹 (1)
        • 모의해킹 스터디 (36)
      • Web (5)
        • 웹 보안 (1)
        • 웹 크롤링 (1)
      • Data (0)
      • Cloud (0)
      • Network (1)
  • 인기 글

  • 방문자 수

    방문자수Total

    • Today :
  • 태그

    상태코드
    hash
    Network
    HttpResponse
    웹해킹
    sqlinjection
    httprequest
    오블완
    웹개발
    HTTP
    mysql
    burpsuite
    javascript
    Chrome
    php
    티스토리챌린지
    메서드
    WEB
    모의해킹스터디
    NAT
    HTML
    SQL
  • hELLO· Designed By정상우.v4.10.1
BPM37093
모의해킹 스터디 3주차 과제(1) - 로그인 케이스 구현
상단으로

티스토리툴바