AesBytesEncryptor
는 Spring Security
가 제공하는 양방향 암호화 클래스이다. 그 중 대칭키 방식을 사용하고, 256-bit AES 알고리즘을 사용한다.
AesBytesEncryptor
를 사용하기 위해서는 Bean등록을 먼저 해줘야한다.
Spring Security를 설정한 Config 파일에 등록을 해주었다.
@Bean
public AesBytesEncryptor aesBytesEncryptor() {
return new AesBytesEncryptor(secret, "70726574657374");
}
secret
은 암호화와 복호화를 해줄 때 필요한 키이다. 키 값은 yml파일에 저장한다음 꺼내 사용하였다.
그리고 뒤에 숫자로 되어있는 문자열은 salt
이다. salt는 암호화해줄 문자열에 저런 임의의 문자열을 덧붙이는걸 의미한다.
만약 비밀번호가 같은 두 사람이 있다고 생각해보자. 만약 한 사람의 비밀번호가 뚫렸다면, 다른 한 사람의 비밀번호도 같기 때문에 똑같이 뚫릴 것이다. 하지만 salt를 사용하면 한 사람이 뚫려도 다른 사람의 비밀번호는 안전하다.
빈 등록한 AesBytesEncryptor
를 사용하기 위해 EncryptService
를 만들어 주었다.
@Service
@RequiredArgsConstructor
public class EncryptService {
private final AesBytesEncryptor encryptor;
public String encryptEmail(String email) {
byte[] encrypt = encryptor.encrypt(email.getBytes(StandardCharsets.UTF_8));
return byteArrayToString(encrypt);
}
public String decryptEmail(String encryptString) {
byte[] decryptBytes = stringToByteArray(encryptString);
byte[] decrypt = encryptor.decrypt(decryptBytes);
return new String(decrypt, StandardCharsets.UTF_8);
}
public String byteArrayToString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte abyte :bytes){
sb.append(abyte);
sb.append(" ");
}
return sb.toString();
}
public byte[] stringToByteArray(String byteString) {
String[] split = byteString.split("\\s");
ByteBuffer buffer = ByteBuffer.allocate(split.length);
for (String s : split) {
buffer.put((byte) Integer.parseInt(s));
}
return buffer.array();
}
}
메소드 하나하나 살펴보자.
public String encryptEmail(String email) {
byte[] encrypt = encryptor.encrypt(email.getBytes(StandardCharsets.UTF_8));
return byteArrayToString(encrypt);
}
이메일만 암호화해주기 때문에 String email을 받는다.
암호화를 해주기 위해서는 byte 배열을 넣어줘야한다.
그리고 암호화를 해주면 byte 배열을 반환해준다. 배열 형태는 BD에 저장을 못 하기 때문에 byte 배열을 String으로 만들어주는 메소드를 구현했다.
public String byteArrayToString(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte abyte :bytes){
sb.append(abyte);
sb.append(" ");
}
return sb.toString();
}
StringBuilder를 사용하여 byte값들을 String으로 만들어주었다.
public String decryptEmail(String encryptString) {
byte[] decryptBytes = stringToByteArray(encryptString);
byte[] decrypt = encryptor.decrypt(decryptBytes);
return new String(decrypt, StandardCharsets.UTF_8);
}
복호화를 하기 위해서는 암호화와 똑같이 byte 배열이 필요하다. 그렇기때문에 String을 byte 배열로 바꿔주는 메소드를 구현하였다.
그리고 중요한점은 복호화를 해준 다음에 반환 받은 byte 배열을 new String()
해서 String 형태로 만들어야한다. toString()을 사용하면 byte 배열의 주소가 반환된다.
public byte[] stringToByteArray(String byteString) {
String[] split = byteString.split("\\s");
ByteBuffer buffer = ByteBuffer.allocate(split.length);
for (String s : split) {
buffer.put((byte) Integer.parseInt(s));
}
return buffer.array();
}
ByteBuffer을 사용하여 String을 byte 배열로 변환해주었다.