Language/Java

[Java] MySQL에 Sha256으로 비밀번호 컬럼 저장하기

The Neo 2023. 3. 30. 17:31

MySQL에서는 sha256_password으로 비밀번호 컬럼을 저장하는 기능이 최근 버전에서 탑재되어 있지만, 여기서는 직접 SHA256 모듈을 호출해서 비밀번호를 저장해보도록 하겠습니다. 

 

[Java] MySQL에 Sha256으로 비밀번호 컬럼 저장하기


Maven, pom.xml

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.27</version>
</dependency>

우선 MySQL에 연결하기 위해서 MySQL Connector/J 라이브러리를 Maven Pom.xml 파일에 Dependency로 추가합니다. 

 

Sha256, Java Code

import java.security.MessageDigest;

public class TestMain {

    public static void main(String[] args) {
        String password = "패스워드";
        String hashedPassword = getSHA256(password);

        System.out.println("Hashed Password: " + hashedPassword);
        System.out.println(hashedPassword.length());
    }

    private static String getSHA256(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(password.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

 

위 예제는 "패스워드" 라는 String 값을 Sha256 암호화 알고리즘을 써서 암호화된 문자열을 받는 예제입니다. 그리고 위의 결과는 아래와 같이 나오게 됩니다.

 

Hashed Password: 69801278b9cef70120c9022b12009d9e69a2b3f4d37704279e10dd50882ca179
64

 

위와 같이 Sha256을 실행하면 64 Byte의 암호화된 문자열이 생성됩니다.

 

 

테스트 테이블

위의 예제를 실행하기 위해서 테스트로 현재 만들고 있는 프로젝트 테이블의 구조를 가져와서 데이터를 넣어보도록 하겠습니다.

 

CREATE TABLE `GPT_MEMBER` (
	  `MEM_ID` varchar(20) NOT NULL COMMENT '사용자ID',
	  `PASSWD` varchar(60) NOT NULL COMMENT '패스워드',
	  `AUTHORITY` varchar(20) NOT NULL COMMENT '권한',
	  `MEM_NM` varchar(10) NOT NULL COMMENT '사용자명',
	  `EMAIL` varchar(50) DEFAULT NULL COMMENT '이메일명',
	  `TEAM` varchar(50) DEFAULT NULL COMMENT '팀명',
	  `REG_USER` varchar(20) NOT NULL COMMENT '등록자',
	  `REG_DT` datetime NOT NULL COMMENT '생성일시',
	  `MOD_USER` varchar(20) NOT NULL COMMENT '수정자',
	  `MOD_DT` datetime NOT NULL COMMENT '수정일시',
	  PRIMARY KEY (`MEM_ID`),
	  KEY `IX01_GPT_MEMBER` (`REG_DT`),
	  KEY `IX02_GPT_MEMBER` (`MOD_DT`)
	) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='GPT 사용자' ;

 

위와 같이 gpt_member라는 테이블에는 패스워드 컬럼이 존재하는데 String에 대응하는 varchar 사이즈를 60으로 잡아서 생성하였습니다. 

 

Insert Java Example

import java.security.MessageDigest;
import java.sql.*;

public class TestMain {

    public static void main(String[] args) {
        String hashedPassword = getSHA256("needneo").substring(0, 60);
        int rc = insertMember("needneo", hashedPassword, "admin", "needneo", "needneo@aaa.com", "매트릭스");
    }

    private static int insertMember(String id, String passwd, String authority, String memNm, String email, String team) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        int rc = 0;

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/my_place?user=root&password=jinhoo80");



            String sql = "INSERT INTO my_place.gpt_member " +
                    "(MEM_ID, PASSWD, AUTHORITY, MEM_NM, EMAIL, TEAM, REG_USER, REG_DT, MOD_USER, MOD_DT) " +
                    "VALUES(?, ?, ?, ?, ?, ?, ?, now(), ?, now())";

            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, id);
            pstmt.setString(2, passwd);
            pstmt.setString(3, authority);
            pstmt.setString(4, memNm);
            pstmt.setString(5, email);
            pstmt.setString(6, team);
            pstmt.setString(7, "admin");
            pstmt.setString(8, "admin");

            rc = pstmt.executeUpdate();
            System.out.println("Member created successfully");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    System.out.println(e.getMessage());
                }
            }
        }

        return rc;
    }

    private static String getSHA256(String password) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            byte[] hash = md.digest(password.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte b : hash) {
                sb.append(String.format("%02x", b));
            }
            return sb.toString();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

 

위 예시를 보면, sha256으로 받은 결과값을 substring하여 60 byte로 바꾼 것을 알 수 있으며, 아래와 같이 passwd 결과가 SHA256으로 암호화하여 저장된 것을 확인하실 수 있습니다. 이렇게 DB에 암호화돼서 저장하게 될 경우, DB 담당자 뿐만 아니라 해킹한테 해킹을 당한다 하더라도 비밀번호를 알 수 없기 때문에 악의적인 이용을 할 수 없게 됩니다. 

 

실행결과

 

 

반응형