본문 바로가기
Develop/Spring Framework

스프링에서 properties 파일을 통해 민감 정보 감추는 방법

by 제이._ 2022. 11. 7.

개발을 하고 서버로 배포를 하면, 민감한 값을 숨겨야 하는 경우가 생깁니다.

데이터베이스 키 값을 숨긴다거나, jwt 키의 값을 숨기는 경우 등등 여러 가지 경우가 있는데, 이번 포스팅은 이에 대해 다룰 예정입니다.

 

데이터베이스 값 감추기

먼저 데이터베이스의 값을 감추는 방법에 대해 말씀드리려고 합니다.

 

기존의 application.yml 파일은 다음과 같습니다.

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/capstone?useSSL=false&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
      use-new-id-generator-mappings: false
    database: mysql
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    properties:
      hibernate:
        show_sql: true
        format_sql: true
        #use_sql_comments: true
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher # about swagger

  servlet.multipart.max-file-size: 5MB
  servlet.multipart.max-request-size: 5MB

우리는 위에서 datasource의 값을 먼저 숨겨보겠습니다!

 

 

1. resources 아래에 application-prod.yml 파일을 하나 만들고 다음과 같이 작성을 해줍니다.

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/capstone?useSSL=false&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

이 파일을 이제 application.yml 에 삽입을 해주도록 하겠습니다.

 

 

 

2. application.yml 에서 아래 코드와 같이 리팩토링을 진행해줍니다.

server:
  port: 8080

spring:
  profiles:
    active: prod

  jpa:
    hibernate:
      ddl-auto: update
      naming:
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
      use-new-id-generator-mappings: false
    database: mysql
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
    properties:
      hibernate:
        show_sql: true
        format_sql: true
        #use_sql_comments: true
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher # about swagger

  servlet.multipart.max-file-size: 5MB
  servlet.multipart.max-request-size: 5MB

 

위와 같이 profiles - active : prod 로 바꾸면서 1번에서 만든 application-prod.yml을 삽입해줬습니다.

자 이대로 멈추면 찜찜하니깐, application-prod.yml의 값도 숨길 수 있게 리팩토링 해보겠습니다.

 

 

 

3. 키 값을 보관할 properties를 하나 만들고, application-prod.yml의 값을 숨기기

저는 키 값을 보관할 aws.properties를 하나 만들고 다음과 같이 입력했습니다.

url:jdbc:mysql://mysqldb:3306/capstone?useSSL=false&useUnicode=true&characterEncoding=utf8&allowPublicKeyRetrieval=true
username=root
password=root

 

그러고 나서 application-prod.yml 에서 아래와 같이 리팩토링을 진행해줍니다.

spring:
  datasource:
    url: ${url}
    username: ${username}
    password: ${password}
    driver-class-name: com.mysql.cj.jdbc.Driver

그러면 위와 같이 aws.properties만 따로 작성해준다면, 서버의 데이터를 안전하게 숨길 수 있게 됐습니다.

이제 마지막 스텝만 진행하면 끝이 납니다.

 

 

4. ~~Application.java 리팩토링

package com.example.capstone;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.PropertySource;

@SpringBootApplication
@PropertySource("classpath:/aws.properties")
public class CapstoneApplication {

    public static void main(String[] args) {
        SpringApplication.run(CapstoneApplication.class, args);
    }

}

위와 같이 @Properties 어노테이션을 추가해주시면 모든 게 끝이 납니다!

이대로 실행을 하면 우리가 원하는 대로 값을 숨긴 상태로 정상 작동됨을 확인하실 수 있습니다.

 

 

 

JWT 시크릿 키 같은 값 숨기기

1. resources 아래에 secure.properties를 만들어주고 아래와 같이 숨길 값을 입력합니다.

jwt.secret=c3ByaW5nLWJvb3Qtc2VjdXJpdHktand0LXR1dG9yaWFsLWppd29vbi1zcHJpbmctYm9vdC1zZWN1cml0eS1qd3QtdHV0b3JpYWwK

저는 jwt의 시크릿키를 숨기고자, jwt.secret이라는 키를 만들었습니다.

 

 

 

2. 고치고자 하는 부분에서 리팩토링 진행해주기

package com.example.capstone.config.jwt;

import com.example.capstone.dto.token.TokenDto;
import io.jsonwebtoken.*;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;


@Slf4j
@Component
@PropertySource("classpath:secure.properties")
public class TokenProvider {

	@Value("${jwt.secret}")
    	private final Key key;

	public TokenProvider(String secretKey) {
        byte[] keyBytes = Decoders.BASE64.decode(secretKey);
        this.key = Keys.hmacShaKeyFor(keyBytes);
    }
    
    .
    .
    .
    생략
    .
    .
    .
    
}

위와 같이 @PropertySouce 속성을 주고, 숨기고자 하는 값 위에 @Value 속성을 통해 값을 주면 됩니다.

import 다른 거와 헷갈리시지 않게 주의해주시면 됩니다. (오류가 난다면 위의 코드 import에서 복붙 하시면 됩니다.)

 

 

예시에서 사용한 yml, properties