Development/Java

JDK8에서 AES 암/복호화 구현하기

bbubbush 2022. 3. 30. 09:13

들어가며

이번 프로젝트에서 A사이트의 암호화된 사용자 정보를 바탕으로 로그인을 연동시키는 기능을 구현했다.

이때 AES, SHA 방식 모두 사용하게 되었고 이참에 자세히 기록하기 위해 글을 적는다.

 

AES 암호화란?

암호화 방식은 아래와 같이 구분할 수 있다.

먼저 복호화가 가능한지에 따라 양방향 / 단방향으로 구분되고,

복호화할 때 사용하는 비밀키가 암호화할 때 그대로 사용되면 대칭키, 서로 다른 키를 사용하면 비대칭키가 된다.

 

AES 알고리즘은 복호화가 가능하며, 동일한 비밀키로 암/복호화를 하기 때문에 대칭키 알고리즘이 된다.

 

반응형

 

코드로 만들어보기

JDK8을 이용해서 개발했고 별도의 라이브러리는 없이 내장된 클래스만 사용하였다. 이렇게 자바 버전을 강조하는 이유는 JDK 11 버전부터는 DatatypeConverter.class를 더 이상 지원하지 않는다. 따라서 Base64나 Hex값으로 인코딩해야 할 경우 별도의 처리가 필요하다.

 

아래는 CBC 타입 / PKCS5Padding 방식을 사용한 구현 코드이다.

public class EncryptService {
  public String encodeAes(String planeText, String secretKey) {
    String encryptText;
    try {
      Key key = new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "AES");
      // CBC 타입을 사용하고, 패딩 알고리즘은 PKCS5Padding 방식을 선택
      Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
		
      // CBC 타입에 필요한 IV 값은 비밀키 앞의 16자리를 사용
      String iv = secretKey.substring(0, 16);
      cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8)));
      
      byte[] encrypted = cipher.doFinal(planeText.getBytes(StandardCharsets.UTF_8));
      encryptText = DatatypeConverter.printBase64Binary(encrypted);
    } catch (GeneralSecurityException e) {
   	  // throws가 싫어서 RuntimeException을 사용
      throw new RuntimeException(e);
    }
    return encryptText;
  }
}

상황에 맞게 변경해야 한다면 "AES/ECB/PKCS5Padding" 처럼 변경해가며 사용하면 된다. 한 가지 유의해야 할 점은 ECB 방식은 IV 값을 사용하지 않기 때문에 cipher.init(mode, key) 형태로 사용하면 된다.

 

마치며

AES는 동일한 비밀키로 암/복호화를 하는 것이 단점으로 야기된다. 그러니 꼭 신뢰할 수 있는 방법으로 비밀키를 전달해야 한다. 

 

본문의 자세한 소스코드를 참고하고 싶다면 아래 github 주소에서 볼 수 있다.

https://github.com/bbubbush/bb-encryption-api

 

GitHub - bbubbush/bb-encryption-api

Contribute to bbubbush/bb-encryption-api development by creating an account on GitHub.

github.com