yaml 설정 파일에 암호화 적용
Jasypt 암복호화 라이브러리 프로젝트에 추가
Section titled “Jasypt 암복호화 라이브러리 프로젝트에 추가”implementation("com.github.ulisesbocchio:jasypt-spring-boot-starter:4.0.3")application.yaml 파일에 비밀번호 추가
Section titled “application.yaml 파일에 비밀번호 추가”jasypt.encryptor.password: 3c8872047fdd4d9e8bfc8c70126d9fed스프링부트 설정 추가
Section titled “스프링부트 설정 추가”@Configurationclass JasyptConfig { private val log = logger()
@Value("\${jasypt.encryptor.password}") private val encryptKey: String? = null
@PostConstruct fun init() { log.debug("encryptKey: {}", encryptKey) }
@Bean("jasyptEncryptor") fun stringEncryptor(): StringEncryptor { val config = SimpleStringPBEConfig() config.setPassword(encryptKey) /*상세 설정정보 생략*/
val encryptor = PooledPBEStringEncryptor() encryptor.setConfig(config) return encryptor }}@Slf4j@Configurationpublic class JasyptConfig {
@Value("${jasypt.encryptor.password}") private String encryptKey;
@PostConstruct public void init() { log.debug("encryptKey: {}", encryptKey); }
@Bean("jasyptEncryptor") public StringEncryptor stringEncryptor() { final SimpleStringPBEConfig config = new SimpleStringPBEConfig(); /*상세 설정정보 생략*/
final PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor(); encryptor.setConfig(config); return encryptor; }}Database ID, 패스워드를 암호화하기 위한 서비스 추가
Section titled “Database ID, 패스워드를 암호화하기 위한 서비스 추가”- Request DTO
JasyptEncryptRequest.kt data class JasyptEncryptRequest(@field:Schema(description = "DB ID", example = "scott")@field:NotBlankvar id: String,@field:Schema(description = "DB 비밀번호", example = "tiger")@field:NotBlankvar password: String,) {fun toContext(): JasyptEncryptContext = JasyptEncryptContext(id, password)}JasyptEncryptRequest.java @Getter@Setter@ToString@AllArgsConstructor@NoArgsConstructor@Builderpublic class JasyptEncryptRequest {@Schema(description = "DB ID", example = "scott")@NotBlankprivate String id;@Schema(description = "DB 비밀번호", example = "tiger")@NotBlankprivate String password;public JasyptEncryptContext toContext() {return JasyptEncryptContext.builder().id(id).password(password).build();}} - Response DTO
JasyptEncryptResponse.kt data class JasyptEncryptResponse(@field:Schema(description = "암호화된 DB ID", example = "4J9sazy6/tZGrKE4/fKR5cfJUpn+yZqs4CD9GrDEDOFLA7WQB63qy46qi0KAXsoa")var encryptId: String,@field:Schema(description = "암호화된 DB 패스워드", example = "4J9sazy6/tZGrKE4/fKR5cfJUpn+yZqs4CD9GrDEDOFLA7WQB63qy46qi0KAXsoa")var encryptPassword: String,)JasyptEncryptResponse.java @Getter@Setter@ToString@AllArgsConstructor@NoArgsConstructor@Builderpublic class JasyptEncryptResponse {@Schema(description = "DB ID", example = "scott")@NotBlankprivate String id;@Schema(description = "DB 비밀번호", example = "tiger")@NotBlankprivate String password;} - Context
JasyptEncryptContext.kt data class JasyptEncryptContext(val id: String,val password: String)JasyptEncryptContext.java @Getter@Setter@ToString@AllArgsConstructor@NoArgsConstructor@Builderpublic class JasyptEncryptContext {private String id;private String password;} - Service
ToolsService.kt fun jasyptEncrypt(context: JasyptEncryptContext): JasyptEncryptContext {try {val encryptId: String = stringEncryptor?.encrypt(context.id) as Stringval decryptId = stringEncryptor.decrypt(encryptId)log.debug("encryptId: {}, decryptId: {}", encryptId, decryptId)val encryptPassword: String = stringEncryptor.encrypt(context.password) as Stringval decryptPassword = stringEncryptor.decrypt(encryptPassword)log.debug("encryptPassword: {}, decryptPassword: {}", encryptPassword, decryptPassword)return JasyptEncryptContext(encryptId, encryptPassword)} catch (e: Exception) {throw BizException(e)}}ToolsService.java public JasyptEncryptContext jasyptEncrypt(final JasyptEncryptContext context) {try {final String encryptId = stringEncryptor.encrypt(context.getId());final String decryptId = stringEncryptor.decrypt(encryptId);log.debug("encryptId: {}, decryptId: {}", encryptId, decryptId);final String encryptPassword = stringEncryptor.encrypt(context.getPassword());final String decryptPassword = stringEncryptor.decrypt(encryptPassword);log.debug("encryptPassword: {}, decryptPassword: {}", encryptPassword, decryptPassword);return JasyptEncryptContext.builder().id(encryptId).password(encryptPassword).build();} catch (final Exception e) {throw new BizException(e);}} - Controller
ToolsController.kt @Operation(summary = "jasypt 암호화", description = "jasypt 암호화 API")@PostMapping("/jasypt-encrypt")fun jasyptEncrypt(@Valid @RequestBody param: RequestDto<JasyptEncryptRequest>): ResponseEntity<ResponseDto<JasyptEncryptResponse>> {log.info("jasyptEncrypt param: $param")val context = param.getPayload()?.toContext() as JasyptEncryptContextval (encryptId, encryptPassword) = toolsService.jasyptEncrypt(context)val payload = JasyptEncryptResponse(encryptId, encryptPassword)return ResponseEntity.ok(ResponseDto(payload))}ToolsController.java @Operation(summary = "jasypt 암호화", description = "jasypt 암호화 API")@PostMapping("/jasypt-encrypt")public ResponseEntity<ResponseDto<JasyptEncryptResponse>> jasyptEncrypt(@Valid @RequestBody RequestDto<JasyptEncryptRequest> param) {JasyptEncryptContext context = param.getPayload().toContext();context = toolsService.jasyptEncrypt(context);final JasyptEncryptResponse payload = JasyptEncryptResponse.builder().id(context.getId()).password(context.getPassword()).build();return ResponseEntity.ok(new ResponseDto<>(payload));}
테스트를 실행해 DB 정보 암호화
Section titled “테스트를 실행해 DB 정보 암호화”- 테스트 추가
IntegrationToolsTest.kt @DisplayName("jasypt 암호화 테스트")@Testfun jasyptEncryptTest() {val param: RequestDto<JasyptEncryptRequest> = RequestDto(JasyptEncryptRequest("@@@@@", "########"))Given {spec(jsonRequestSpecification)body(param)} When {post("/tools/jasypt-encrypt")} Then {statusCode(HttpStatus.SC_OK)} Extract {println(body().asString())}}ToolsTest.java @DisplayName("Jasypt 암호화 테스트")@Testvoid testJasyptEncrypt() {final RequestDto<JasyptEncryptRequest> param = new RequestDto<>(JasyptEncryptRequest.builder().id("gangil").password("abcd4321").build());given().spec(jsonRequestSpecification).body(param).when().post("/tools/jasypt-encrypt").then().statusCode(HttpStatus.SC_OK).body("successYn", equalTo("Y"),"messageCd", equalTo("SUCCESS"),"payload", notNullValue(),"payload.id", notNullValue(),"payload.password", notNullValue()).log().all();} - 로그
2026-02-23 20:16:30,725 [INFO ] [http-nio-auto-1-exec-2] b.m.c.a.t.c.ToolsController: jasyptEncrypt param: RequestDto(payload=JasyptEncryptRequest(id=@@@@@, password=########))2026-02-23 20:16:30,807 [DEBUG] [http-nio-auto-1-exec-2] b.m.c.a.t.s.ToolsService: encryptId: acH4xx7YOmAp2hEBCXrn27lCQxMfu7p0x7kiBX9yIp/soU/TiMVHPW1FU86NxhDJ, decryptId: @@@@@2026-02-23 20:16:30,813 [DEBUG] [http-nio-auto-1-exec-2] b.m.c.a.t.s.ToolsService: encryptPassword: 7mhs2XZAcN60mwAqzOXEzHNEtKS4JzARVYeni3dNSNmCWF+0sg37//GBTMyEJrCv, decryptPassword: @@@@@{"payload":{"encryptId":"acH4xx7YOmAp2hEBCXrn27lCQxMfu7p0x7kiBX9yIp/soU/TiMVHPW1FU86NxhDJ","encryptPassword":"7mhs2XZAcN60mwAqzOXEzHNEtKS4JzARVYeni3dNSNmCWF+0sg37//GBTMyEJrCv"},"isSuccess":true,"resultCode":"SUCCESS","message":null}HTTP/1.1 200Vary: OriginVary: Access-Control-Request-MethodVary: Access-Control-Request-HeadersX-Request-ID: 085937X-Content-Type-Options: nosniffX-XSS-Protection: 0Cache-Control: no-cache, no-store, max-age=0, must-revalidatePragma: no-cacheExpires: 0X-Frame-Options: DENYContent-Type: application/jsonTransfer-Encoding: chunkedDate: Sun, 01 Mar 2026 13:22:57 GMTKeep-Alive: timeout=60Connection: keep-alive{"payload": {"id": "XBjBpxVlcireIYEYj7NiB0lBh4fymtAb7Epds+rFr2cXciP0zlI74ocPH56kQ9bY","password": "oYn/6lbTQX//llfw9WOxGLK0cbNz7xcoOlyLN4tACoMIs1HrdSToMPrhBcQVjjXD"},"successYn": "Y","messageCd": "SUCCESS"}
application.yaml 파일에 적용
Section titled “application.yaml 파일에 적용”spring: datasource: url: jdbc:mysql://10.178.0.16:3306/carrot?characterEncoding=UTF-8&serverTimezone=UTC&allowPublicKeyRetrieval=true&useSSL=false username: ENC(kk1ZbLDUd728voi60PrRNg+teiQq6QoCLXyHy1hgq31TNHtxEJ5fJ5iV9tb4jkON) password: ENC(WMJnzdq9NVM2M6AQIvLUFCQJupUUlTUX7/hbuT9sX7aORtpP/EtS+vzKuLllDtOQ) driver-class-name: com.mysql.cj.jdbc.Driver