[Java] SHA-256 해싱(Hashing) 알고리즘 사용법

    비트코인에서 쓰고 있기도 한 해싱 알고리즘인 SHA-256은, 안전한 해시 알고리즘인 Secure Hash Algorithm에서 따온 명칭이다. 이 함수는 미국 국가안보국(NSA)에서 1993년 처음 설계했으며, 미국 국가 표준으로 지정되었다.


    1993년에 SHA-0 버전을 시작으로, SHA-1은 1995년에 나왔고, SHA-2는 2001년 SHA-3은 2012년에 나오게 된다. 여기서 설명할 SHA-256은 SHA-2 중에 하나로서, SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256 패밀리를 보유하고 있다.


    SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of six hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256.


    https://en.wikipedia.org/wiki/SHA-2


    SHA-0 버전과 SHA-1 버전의 경우, 해독의 가능성과 해시 충돌이 발생하였기 때문에, 2015년엔 주요 브라우저에서도 지원 중단을 하였고, 아직 SHA-2는 이 문제가 발생하지 않았지만 알고리즘이 SHA-1과 별반 다르지 않아 추후 문제가 발생될 여지는 있다. 



    Java 사용 방법


    Java에서 기본적으로 SHA나 기타 다른 해시 알고리즘을 사용할 수 있는 라이브러리(Library)를 제공하고 있는데, "java.security.MessageDigest"를 사용하면 된다. 


    Every implementation of the Java platform is required to support the following standard MessageDigest algorithms:


    MD5

    SHA-1

    SHA-256

    These algorithms are described in the MessageDigest section of the Java Cryptography Architecture Standard Algorithm Name Documentation. Consult the release documentation for your implementation to see if any other algorithms are supported.


    https://docs.oracle.com/javase/7/docs/api/java/security/MessageDigest.html


    위 내용처럼, MessageDigest는 MD5, SHA-1, SHA-256을 사용하고 있으며, 위의 내용처럼 SHA-1은 사용하는 것을 권장하지 않기 때문에 SHA-256을 쓰는 것이 좋다.


    호출 메소드

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /**
     * SHA-256으로 해싱하는 메소드
     * 
     * @param bytes
     * @return
     * @throws NoSuchAlgorithmException 
     */
    public static byte[] sha256(String msg) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(msg.getBytes());
        
        return md.digest();
    }
    cs


    SHA-256을 호출, 리턴을 byte[]로 받기 때문에 String으로 변환이 필요하다.



    변환 메소드, 1

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    /**
     * 바이트를 헥사값으로 변환한다, type 1
     * 
     * @param bytes
     * @return
     */
    public static String bytesToHex1(byte[] bytes) {
        StringBuilder builder = new StringBuilder();
        for (byte b: bytes) {
          builder.append(String.format("%02x", b));
        }
        return builder.toString();
    }
    cs



    변환 메소드, 2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /**
     * 바이트를 헥사값으로 변환한다, type 2
     * 
     * @param bytes
     * @return
     */
    public static String bytesToHex2(byte[] bytes) {
        char[] hexChars = new char[bytes.length * 2];
        for ( int j = 0; j < bytes.length; j++ ) {
            int v = bytes[j] & 0xFF;
            hexChars[j * 2= hexArray[v >>> 4];
            hexChars[j * + 1= hexArray[v & 0x0F];
        }
        return new String(hexChars);
    }
    cs


    변환 메소드 2 타입 방식은 hexArray에 hexa 값을 넣는데, hexArray에 대한 선언은 메소드 안에 해주거나, 전역변수에 넣어서 사용을 한다. 


    1
    final static char[] hexArray = "0123456789abcdef".toCharArray();
    cs



    호출

    1
    2
    3
    4
    5
    public static void main(String[] args) throws Exception {
            
        System.out.println(bytesToHex1(sha256("needjarvis")));
        System.out.println(bytesToHex2(sha256("needjarvis")));        
    }    
    cs


    위와 같이 sha256 메소드에 값을 넣어서 호출 한 후, 다시 bytesToHex1,2 메소드에 넣어서 변환을 시킨다.



    결과

    f204250d7fd90ceebca11068ecf17318b554d06808b4615ca3e7347e08947816

    f204250d7fd90ceebca11068ecf17318b554d06808b4615ca3e7347e08947816


    둘 중에, 한가지 메소드를 선택 한 후, 아래와 같이 sha256 메소드 안에, 적용을 하도록 하자.



    최종예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    package com.tistory.needjarvis;
     
    import java.security.MessageDigest;
    import java.security.NoSuchAlgorithmException;
     
    public class main {
        public static void main(String[] args) throws Exception {
            System.out.println(sha256("needjarvis"));        
        }
     
     
        /**
         * SHA-256으로 해싱하는 메소드
         * 
         * @param bytes
         * @return
         * @throws NoSuchAlgorithmException 
         */
        public static String sha256(String msg) throws NoSuchAlgorithmException {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            md.update(msg.getBytes());
            
            return bytesToHex1(md.digest());
        }
     
     
        /**
         * 바이트를 헥스값으로 변환한다
         * 
         * @param bytes
         * @return
         */
        public static String bytesToHex(byte[] bytes) {
            StringBuilder builder = new StringBuilder();
            for (byte b: bytes) {
              builder.append(String.format("%02x", b));
            }
            return builder.toString();
        }
    }
    cs

    댓글

    Designed by JB FACTORY