본론부터 가자

양방향 암호화 (복호화 가능) 과 단방향 Hash 데이터가 있다.

 

우선 Hash 에 대해 간단히 설명하자

 

- Hash Algorithm을 이용하여 원문 데이터 길이와 무관하게 항상 고정된 길이로 Hash 데이터를 생성한다.

 

- Hash Algorithm 은 모두 공개되어 있기 때문에 사용해서는 안되는 Algorithm 이 있다.

  ( 권장되지 않는 Hash Algorithm : MD5, SHA-1, HAS-180 )

 

- 위에서 언급한 대로 원문(입력값) 은 무한대 이지만 Hash 된 값은 항상 고정된 길이 값으로

   나타내기 때문에 중복되는 Hash 값이 나올 수가 있다. (확률은 낮고, 중복 최소화를 위해 Algorithm 이 생겨난듯...)

 

- Hash 데이터는 복호화가 되지 않는다. 즉 데이터의 무결성을 검증 할 수 있는 Signatrue 데이터 이다. 

 

여기서는 Hash 데이터 생성 방법 중 SHA-256HMAC 에 대한 간단한 샘플을 기재한다. 

 

[ SHA-256 ]

 

: SHA ( Secure Hash Algorithm )

import java.security.MessageDigest;

import java.securit.NoSuchAlgorithmException;

import java.util.Base56;


public class SHA256Test
{
    public static void main( String[] args )
    {
        String plainData = "ABCDEFG^1234^!@#$";
        
        SHA256Test shaTest = new SHA256Test();
        String hashData = shaTest.sha256Hash( plainData );

        System.out.println( "SHA_256 : " + hashData );
        System.out.println( "SHA_256.len : " + hashData.getBytes().length );
    }

    public String sha256Hash( String plainData )
    {
        try {
            MessageDigest md = MessageDigest.getInstance( "SHA-256" );
            md.update( plainData.getBytes() );
            return bytesToHex( md.digest() );
        } catch( NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
    }

    // byte 데이터를 16진수 String 데이터로 변환    
    public String bytesToHex( byte[] btArrData )
    {
        StringBuffer strBuf = new StringBuffer();
        
        for( byte bt : btArrData )
        {
            strBuf.append( String.format( "%02x", bt ) );
        }

        return strBuf.toString();
    }
    
}

 

[ SHA256 결과 ]

SHA_256 : 218d186.................................~~.......................................2835ceeb
SHA_256.len : 64

위와 같은 결과가 나온다. 

위에서 plainData 값을 늘리거나 줄이거나 하여도 길이는 항상 64가 나온다. 

이유는 간단하다.

sha-256 알고리즘은 데이터를 hash 할 때 항상 256 bit 로 변환이 된다. 

 

16진수는 1자리가 4 bit 이며, sha-256 문자열 길이가 64 byte 이면

64 * 4 = 256 bit 가 되기 때문이다.

 

 

[ HMAC ]

 

HMAC : Hash based Message Authentication Code - 인증된 메세지 코드 라는 뜻이다

- 위 처럼 HMAC 는 hash 기반의 인증이 포함된 메세지이다.

  HMAC 은 위 SHA-256 과 달리 Key가 필요하며, Hash based 의 무결성과 Key 을 이용한 인증 

  2가지를 다 제공하고 있다. 

 

아래 예제는 HMAC_SHA256 데이터를 만드는 샘플이다. 

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

public class HMAC_SHA256Test
{
    public static final String HMAC_ALG = "HmacSHA256";


    public static void main( String[] args )
    {
        String plainData = "ABCDEFG^1234^!@#$";
        String hmacKey  = "TEST1234567890";
        
        HMAC_SHA256Test hmacTest = new HMAC_SHA256Test();

        String hmacData= hmacTest.getHMacData( plainData, hmacKey );

        System.out.println( "HMAC_SHA_256 : " + hashData );
        System.out.println( "HMAC_SHA_256.len : " + hashData.getBytes().length );
    }


    public String getHMacData( String plainData, String hmacKey )
    {
        try {

            // HMAC Hash 알고리즘 & Key 설정
            Mac mac = Mac.getInstance( HMAC_ALG );
            mac.init( new SecretKeySpec( hmacKey.getBytes(), HMAC_ALG ) );

            // HMAC 데이터 생성.
            byte[] btArrHmacData = mac.doFinal( plainData.getBytes() );

            String hmacData = bytesToHex( btArrHmacData );


        } catch( NoSuchAlgorithmException e ) {
            e.printStackTrace();
            return null;
        } catch( InvalidKeyException e ) {
            e.printStackTrace();
            return null;
        }

    }


    // byte 데이터를 16진수 String 데이터로 변환    
    public String bytesToHex( byte[] btArrData )
    {
        StringBuffer strBuf = new StringBuffer();
        
        for( byte bt : btArrData )
        {
            strBuf.append( String.format( "%02x", bt ) );
        }

        return strBuf.toString();
    }


}

 

위 main 함수 실행 시 다음과 같은 결과가 나온다. 

HMAC_SHA_256 : 1424fe73f7e ~~~  426b87b
HMAC_SHA_256.len : 64

 

결론 : Hash 를 암호화라고 생각할 수 있으나 위에서 언급했던것 과 같이 Hash 는 복호화가 불가능하며, 

        Hash 데이터 검증을 위해서는 원문데이터가 필요하거나 또는 원문 + Key 값이 필요하다. 

 

이렇게 간단히 Hash 데이터를 만드는 방법을 알아보았다. 

이 방식 외 공개키 개인키로 Signatrue 데이터를 만들어 verify 하는 방법도 있으나, 해당 내용은

다음에 알아보도록 하겠다. 

'Development > JAVA' 카테고리의 다른 글

Oracle OpenJDK 11 버그로 인한 AdoptJDK 다운  (0) 2021.01.16
java 날짜 계산 (java.time)  (0) 2020.11.03
PKCS 표준 정보  (0) 2020.10.26
Open JDK 다운로드  (0) 2020.04.22
Java Caller & Callee 확인하기  (0) 2020.04.17

+ Recent posts