ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링(Spring) SHA-256 알고리즘 이용한 비밀번호 암호화
    보안(Security)/Login, Password Policy 2018. 9. 10. 09:48

    DB에는 다양한 정보들이 있는데, 개인을 지칭할  있는 정보를 노출하지 않도록 노력하는것이 의무화 되어 있다. 이를 위해 다양한 데이터들을 암호화 및 복호화를 통해 보안을 강화한다.

    암호화된 데이터를 복원할 수 있느냐(복호화가 되느냐) 안되느냐에 따라 암호화 강약을 가늠할  있다.
    노출됐을  미칠 영향력에 따라 암호화 강화 정도를 정한다.

    비밀번호바이오 정보 암호화 강도가 높아야 하는 데이터 : 일방향 암호화 (복호화 X) 해쉬함수 사용
    나머지 암호화 필요한 정보 : 블록 암호복호화 가능

    과거에는 복호화가 가능한 블록암호를 사용했지만 오늘날 대부분 데이터를 암호화할 때 일방향 암호화 알고리즘을 사용한다. 대표적으로 SHA-256, SHA-512 등이 있다. 그중 SHA-256을 통한 비밀번호 암호화 과정 포스팅.
     

    SHA는 Secure Hash Algorithm의 약어로 해쉬함수를 사용하는 암호화 알고리즘이다. 자바에서는 security 패키지를 통해 이를 지원한다. 간략한 절차는 다음과 같다.

    1) 회원가입을 할 때 비밀번호를 받아 암호화 한다.
    - 암호화 할 때 짝을 이루는 난수를 발생시켜 암호화에 이용한다. 이 난수를 일컬어 Salt라 한다.
    - DB에 암호화된 비밀번호와 Salt 값을 저장한다.

    2) 로그인할 때 ID에 맞는 Salt 가져온다.

    3) 입력한 Password와 Salt를 통해 암호화 시킨 값을 비밀번호로 해 쿼리문을 수행한다.


     DB에 SALT를 추가한다.
    * Salt 값은 복호화에 있어 중요한 단서기 때문에 이또한 그대로 저장하지 않는다. 실무에서는 다른 서버에 SATL값만을 가지는 DB 두거나 SALT를 양방향 암호화 하도록 한다.
    * 비밀번호가 암호화 돼 길어지기 때문에 사이즈를 넉넉하게 해야 한다.


    SHA-256 알고리즘 지원하는 클래스 작성




    package kr.co.hucloud.utilities;
    
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
    import java.util.Random;
    
    /**
     * SHA-256 암호화
     * 
     * @author Minchang Jang
     *
     */
    public class SHA256Util {
    
    	/**
    	 * SHA-256 암호화 함
    	 * @param source 원본
    	 * @param salt(String) SALT 값
    	 * @return
    	 */
    	public static String getEncrypt(String source, String salt) {
    		return getEncrypt(source, salt.getBytes());
    	}
    	
    	/**
    	 * SHA-256 암호화 함
    	 * @param source 원본
    	 * @param salt(byte[]) SALT 값
    	 * @return
    	 */
    	public static String getEncrypt(String source, byte[] salt) {
    		
    		String result = "";
    		
    		byte[] a = source.getBytes();
    		byte[] bytes = new byte[a.length + salt.length];
    		
    		System.arraycopy(a, 0, bytes, 0, a.length);
    		System.arraycopy(salt, 0, bytes, a.length, salt.length);
    		
    		try {
    			// 암호화 방식 지정 메소드
    			MessageDigest md = MessageDigest.getInstance("SHA-256");
    			md.update(bytes);
    			
    			byte[] byteData = md.digest();
    			
    			StringBuffer sb = new StringBuffer();
    			for (int i = 0; i < byteData.length; i++) {
    				sb.append(Integer.toString((byteData[i] & 0xFF) + 256, 16).substring(1));
    			}
    			
    			result = sb.toString();
    		} catch (NoSuchAlgorithmException e) {
    			e.printStackTrace();
    		}
    		
    		return result;
    	}
    	
    	/**
    	 * SALT를 얻어온다.
    	 * @return
    	 */
    	public static String generateSalt() {
    		Random random = new Random();
    		
    		byte[] salt = new byte[8];
    		random.nextBytes(salt);
    		
    		StringBuffer sb = new StringBuffer();
    		for (int i = 0; i < salt.length; i++) {
    			// byte 값을 Hex 값으로 바꾸기.
    			sb.append(String.format("%02x",salt[i]));
    		}
    		
    		return sb.toString();
    	}
    	
    }
    
    

    SHA256Util.java 적당한 곳(유틸 파일 패키지)에 저장한다.

    주요 메소드 


     메소드명

     반환값

     설명

     getEncrtpy(password, salt)

     String

     난수 salt 발생시킴

     generateSalt()

     String

     비밀번호와 salt를 조합해 암호화 시킴


    회원가입 Service 메소드. 난수 salt를 발생시키고 비밀번호를 난수화 함께 암호화한다.
    - 이후 salt와 password를 set 해주고 다음 로직을 수행하면 된다.

    DB에 접근해 ID에 해당하는 salt 값을 가져오는 메소드 getSaltById를 추가해야 한다. 
    (쿼리문은 "SELECT SALT FROM MBR WHERE MBR_ID = ?" 를 사용하면 됨)

    - 로그인 Service 메소드. 로그인 정보 중 ID에 맞는 salt값을 가져온 후 password와 함께 암호화 수행한 다.
    - 암호화 한 값을 비밀번호로 set 해준 후 쿼리를 통해 일치하는 값이 있는지 비교한다.


    DB에는 다음과 같이 의미 없는 값들이 들어와 DB를 해킹당해도 비밀번호를 직접적으로 노출당할 우려를 줄인다.







Designed by Tistory.