JPA를 사용해 MongoDB를 연동하는 과정에서 MongoDB 내에 값을 암호화해야 하는 경우가 있다.
이에 spring-data-mongodb-encrypt 라는 암호화 모듈 제공파일을 사용하여 구현하게 되었다. (링크)
※사용 전 숙지사항
DB에 저장하기 전이나 불러온 후에는 값이 복호화된 상태로 존재하기 때문에, 응용 내에서도 암호화된 상태로 유지가 필요하다면 별도의 암호화 툴을 사용하는 것이 좋다.
pom.xml
Spring Boot 전용 MongoDB JPA 및 MongoDB 암호화 모듈을 추가한다.
<!-- Spring Data JPA - MongoDB --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> <!-- Spring Data JPA - MongoDB Encrypt --> <dependency> <groupId>com.bol</groupId> <artifactId>spring-data-mongodb-encrypt</artifactId> <version>2.4.4</version> </dependency>
MongoDBConfiguration.java
MongoDB JPA가 Spring Boot용 모듈이므로, application.properties나 application.yaml이 아닌 Java Config로 별도로 설정이 필요하다.
이 때, 기본적인 MongoDB 연동 과정 또한 마찬가지로 Spring Boot JPA 단에서 자체적으로 이루어지기 때문에 Java Config 생성 시에 가이드에 나온것처럼 AbstractMongoClientConfiguration 클래스를 상속받지 않도록 주의해야 한다.
@Configuration public class MongoDBConfiguration { private static final byte[] oldKey = Base64.getDecoder().decode("cUzurmCcL+K252XDJhhWI/A/+wxYXLgIm678bwsE2QM="); // 키 값은 임의로 변경하여 사용한다. private static final byte[] secretKey = Base64.getDecoder().decode("hqHKBLV83LpCqzKpf8OvutbCs+O5wX5BPu3btWpEvXA="); // 마찬가지로, 변경하여 사용한다. @Bean public CryptVault cryptVault() { return new CryptVault() .with256BitAesCbcPkcs5PaddingAnd128BitSaltKey(0, oldKey) .with256BitAesCbcPkcs5PaddingAnd128BitSaltKey(1, secretKey) .withDefaultKeyVersion(1); } @Bean public CachedEncryptionEventListener encryptionEventListener(CryptVault cryptVault) { return new CachedEncryptionEventListener(cryptVault); } }
MyDTO.java
DTO용 클래스를 선언한다. 상단에 선언된 Lombok 애노테이션은 생략 가능하다.
@Getter @Setter @SuperBuilder @NoArgsConstructor @ToString public class MyDTO { private String userId; @Encrypted private String password; }
MyEntity.java
MyDTO를 상속하는 엔티티 클래스로, MyDTO의 @Encrypted가 선언된 password 설정을 유지한 상태로 가져오게 되어 MongoDB에 Insert하면 암호화된 값을 저장하게 된다.
마찬가지로 상단의 Lombok 애노테이션은 생략이 가능하며, 굳이 MyDTO를 상속받지 않고 따로 엔티티 클래스 내에 @Encrypted가 붙은 필드를 선언하여 사용해도 된다.
@Getter @SuperBuilder @AllArgsConstructor @NoArgsConstructor @ToString @Document(collection = "account") public class MyEntity extends MyDTO { @Id private String id; }