박서희연구소

Java AES256 에 대해서(암호화, 복호화) 본문

○ Programming [Basic]/Security

Java AES256 에 대해서(암호화, 복호화)

SEOHUI PARK 2020. 1. 23. 13:31
반응형

개요

오늘날 보안의 중요성은 굉장히 중요한데, Java 는 해싱 알고리즘과 서로 다른 암호화를 지원해 데이터 전송 및 여러 노드 간의 통신에 대한 보안을 제공한다. 

이중 고급 암호화 표준 알고리즘인 AES256 에 대해 알아본다.

  • 대칭 타입의 블록 암복호화
  • 128, 192, 256 와 같은 다양한 padding bit 를 사용하여 암호화
  • 암호화와 복호화에 모두 유효하며, 유사한 비밀 키를 사용
  • 블록 암호를 사용하며, 이는 데이터 암호화를 위해 데이터가 블록으로 변환하는 것을 의미함

AES 의 장점

  • 암호화된 데이터는 유효한 비밀 키 없이는 복호화 할 수 없음
  • 무선 통신, 금융 거래, 암호화된 데이터 저장과 같은 다양한 목적으로 전 세계적으로 사용되는 가장 일반적인 보안 알고리즘
  • 데이터가 깨지지 않고 안정하게 전송 가능

AES 의 단점

  • 매우 간단한 대수 공식 사용
  • 각 블록은 유사한 종류의 암호화를 사용
  • 소프트웨어로 구현하기 어려울 수 있음

원리

AES 알고리즘 원리

  • 일반 텍스트 메시지는 메시지의 발신자와 수신자만 알 수 있는 비밀 키를 사용하여 암호화된 텍스트로 변환
  • 메시지, 문자열의 암복호화는 Java 의 JCE(Java Cryptographic Extension) 프레임워크에서 지원
  • 메시지 복호화에는 암호화의 과정의 역순이되며, 원본의 메시지를 획득하려면 비밀 키가 필요
  • Java 의 Cipher Class 는 암호화 및 복호화 프로세스에 사용되며, init() 메서드는 공개 키를 사용하여 암호를 초기화

padding 이란?

아래 코드에도 나오겠지만, 위에서 블록 암호화 를 진행하기 위해서는 패딩 기법 이 필요하다. 데이터를 특정 크기로 맞추기 위해서, 특정 크기보다 부족한 부분의 공간을 의미없는 문자들로 채워서 비트수를 맞추는 것으로 암호화 시에는 반드시 필요한 방법이다.

다음과 같이 쓰일수 있다.

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

적용 예

public class AESTest {

    private static final String SECRET_KEY = "123456789";
    private static final String SALTVALUE = "seohui";

    public static String encrypt(String stringToEncrypt) {
        try {
            // byte array 선언
            byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            // 비밀 키를 위한 factory 생성
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");

            KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALTVALUE.getBytes(), 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);

            return Base64.getEncoder().encodeToString(cipher.doFinal(stringToEncrypt.getBytes(StandardCharsets.UTF_8)));
        } catch (InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e) {
            System.out.println("Error: " + e.toString());
        }
        return null;
    }

    public static String decrypt(String stringToEncrypt) {
        try {
            // byte array 선언
            byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
            IvParameterSpec ivspec = new IvParameterSpec(iv);
            // 비밀 키를 위한 factory 생성
            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");

            KeySpec spec = new PBEKeySpec(SECRET_KEY.toCharArray(), SALTVALUE.getBytes(), 65536, 256);
            SecretKey tmp = factory.generateSecret(spec);
            SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivspec);

            return new String(cipher.doFinal(Base64.getDecoder().decode(stringToEncrypt)));
        } catch (InvalidAlgorithmParameterException | InvalidKeyException | NoSuchAlgorithmException | InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e) {
            System.out.println("Error: " + e.toString());
        }
        return null;
    }

    public static void main(String[] ags) {

        // 원본 메시지
        String originalValue = "Seohui Text AES Encryption";
        // 암호화된 메시지
        String encryptedValue = encrypt(originalValue);
        // 복호화된 메시지
        String decryptedValue = decrypt(encryptedValue);

        System.out.println("Original value: " + originalValue);
        System.out.println("Encrypted value: " + encryptedValue);
        System.out.println("Decrypted value: " + decryptedValue);
    }
}

 

- 끝 -

반응형
Comments