AES-256-GCM 으로 암호화된 개인정보 Java로 복호화하기
django 서버의 개인정보를 AES-256-GCM 알고리즘으로 암호화하기
이번 작업은...성능이 매우 낮은 레거시를 쳐내는 작업이었다. 이번 작업의 요구사항은 아래와 같이 정의할 수 있었다. 성능이 기존보다 빨라야 할 것 aws KMS를 사용하고 있었는데 네트워크를 타야하다보니 암호화가 느렸다. 개인정보를 암호화하는 데 이것보다는 훨씬 성능이 빨라야 한다. 법률을 준수하는 보안 설계프로젝트 수행 시 정보 시스템을 구축하게 되고 정보 시스템을 보호하기
위의 포스트를 통해 저장한 전화번호 "01033336666" 의 실제 데이터베이스 저장값은
v=1,a=aes256gcm,3uiCUhKGdcIbcZcXU5wCzw==,t6YzJ8BWI7stb+U=,R1kgOsyI/vJRwbX2cN9/bg==
이다. ,
를 통한 데이터 구분을 통해 암호화의 정보를 저장하였다. 실제로 우리가 복호화 (decryption)에 필요한 것은 IV (nonce) 와 Cipher Text 그리고 Tag 이다. 위 값에서 각각의 값은,
- IV (Nonce) :
3uiCUhKGdcIbcZcXU5wCzw==
- Cipher Text :
t6YzJ8BWI7stb+U=
- Tag :
R1kgOsyI/vJRwbX2cN9/bg==
모두 Base64로 인코딩된 바이트이므로 아래의 과정을 거쳐야한다.
Decoder decoder = Base64.getDecoder();
byte[] nonce = decoder.decode("3uiCUhKGdcIbcZcXU5wCzw==");
byte[] cipherText = decoder.decode("t6YzJ8BWI7stb+U=");
byte[] tag = decoder.decode("R1kgOsyI/vJRwbX2cN9/bg==");
이다. 우리는 Java 스탠다드 라이브러리만으로 암호를 Encrypt / Decrypt 할 것이다. python의 라이브러리와 다르게 byte[] cipherText
는 python 구현체의 결과물인 Cipher Text와 Tag가 연결된 바이트이다. 그러므로 아래와 같은 작업을 해주어야 한다.
public byte[] getCipherTextAndTag() {
Decoder decoder = Base64.getDecoder();
byte[] cipherText = decoder.decode("t6YzJ8BWI7stb+U=");
byte[] tag = decoder.decode("R1kgOsyI/vJRwbX2cN9/bg==");
return Bytes.concat(this.cipherText, this.tag);
}
이 합쳐진 바이트를 이용해야 한다.
public static String decrypt(byte[] cipherText, byte[] nonce) throws Exception {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(getKey(), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(GCM_TAG_LENGTH * 8, nonce);
cipher.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText);
}
복호화하는 메소드이다.
getKey()
: 암호화 키를 반환하는 메소드다.byte[]
타입으로 반환한다.gcmParameterSpec
: Nonce, 즉 IV이다.cipher.init
: 복호화를 위한 초기화이다.
구현체는 아래를 통해 확인할 수 있다.
GitHub - byunjuneseok/java-aes-256-gcm-poc
Contribute to byunjuneseok/java-aes-256-gcm-poc development by creating an account on GitHub.