ISMS 비밀번호 SHA-256 암호화

김철현·2021년 6월 22일
0

Encryption

목록 보기
4/5
post-thumbnail

📝 배경

ISMS 암호화 키관리(AES-128 양방향 암호화)
기존 비밀번호 저장 방식이 앞서 포스팅 했던 내용과 같이 AES128 양방향 암호화 방식을
사용하고 있어 복호화 할 수 없는 단방향 암호화를 사용해야 한다고 지적 받아
해당 내용에 대해 포스팅 하게 됨

📝 암호화 방식 선택기준

무결성을 위한 암호 기술은 최소 128비트 암호화키를 사용하는 SHA-256 이상의
해쉬함수와 같은 안전성이 입증된 단방향암호화 알고리즘을 이용하여 복호화되지 않토록 한다
(암호화 대상 정보: 비밀번호, 배포프로그램 등)

보안강도 해시 함수 안정성
80bit 미만 MD5, SHA-1 권고하지 않음
80bit HAS-160 권고하지 않음
112bit SHA-224 권고하지 않음
128bit SHA-256 권고
192bit SHA-384 권고
256bit SHA-512 권고

📝 해쉬함수 비교

알고리즘 해시값 크기 내부 상태 크기 블록 크기 길이 한계 워드 크기 과정 수 충돌
SHA-0 160 160 512 64 32 80 발견됨
SHA-1 160 160 512 64 32 80 발견됨
SHA-256/224 256/224 256 512 64 32 64 -
SHA-512/384 512/384 512 1024 128 64 80 -

📝 구현

위와 같은 기준으로 아직 충돌이 발견되지 않은 암호길이가 64 byte인 SHA-256를 사용했다
하지만 오라클 12이상 버전에서는 DBMS_CRYPTO 패키지에서 SHA-256 암호화를 지원하지만
현재 재직중인 회사 버전은 11g로 지원하지 않아 AES-128과 같이 자바 모듈(jar파일)을 만들게 됨

✍ 모듈 소스

package com.erp.common;

import java.security.MessageDigest;

public class SHA256 {
	
    public String encrypt(String str){
    	try{
    		//해쉬함수 SHA-256 인스턴스 생성
    		MessageDigest md = MessageDigest.getInstance("SHA-256");
    		//digest 계산
    		md.update(str.getBytes("UTF-8"));
    		//암호화 후 16진수로 변환 후 리턴
    		return byteArrayToHex(md.digest()).toUpperCase();
    	}
    	catch(Exception e){
    		return null;
    	}
    }

    //byte[]->hex String
    private String byteArrayToHex(byte[] encrypted) {
        
        if(encrypted == null || encrypted.length == 0){
            return null;
        }
        
        StringBuffer sb = new StringBuffer();
        for (byte b : encrypted) {
        	//앞 빈자리 0으로 채우는 16진수 (16진수는 2자리)
        	sb.append(String.format("%02x", b));
        }
        return sb.toString();
    }
}

✍ 모듈 호출 소스

AES-128과 같이 Util 클래스에 static 함수 추가

public class Util{
  public static String getSHA256(String plainText){
    SHA256 sha256 = new SHA256();
    String encText = null;
    try { 
         encText = sha256.encrypt(plainText);
        } 
    catch (Exception e) {
          e.printStackTrace();
    }
    finally{
      return encText;
    }
  }
}

✍ 서비스에서 쿼리에 사용될 DataMap paramData에 값 저장

//함수 내 쿼리실행 변수에 할당
public String insertMember(DataMap paramData){
  paramData.put("pwd", Util.getSHA256(paramData.get("pwd")));
}
profile
리팩토링만이 살 길이다

0개의 댓글