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

    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 담당자 뿐만 아니라 해킹한테 해킹을 당한다 하더라도 비밀번호를 알 수 없기 때문에 악의적인 이용을 할 수 없게 됩니다. 

     

    실행결과

     

     

    반응형

    댓글

    Designed by JB FACTORY