728x90

비교적 오랜만에 글을 업로드 하는 것 같다.

사이드 프로젝트와 여러가지 업무에 매진해서 블로그 포스팅할 새도 없이 쭉 지나갔다.

모든 코드는 깃허브에 있다.

이번 포스팅에서는 Encyption 즉, 암호화에 대해서 다뤄보겠습니다.

서론

우선 현재 저희가 쓰고있는 암호화에는 각종 Open Api 클라이언트 ID와 비밀번호에 대해 암호화를 적용하였습니다.

스크린샷 2021-09-12 오후 8 37 13

예시로 하나의 암호화된 아이디와 패스워드를 가져왔습니다.

Github 또는 그 외의 공개 장소에 프로젝트 관리를 하다보면 DB 패스워드 등 보안에 민감한 정보들이 노출되기 쉽습니다.

그렇기 때문에 이런 민감한 정보들은 암호화를 해주어야 합니다.

그냥 명시적으로 적어두게 되면 누군가가 이 아이디와 암호를 보고 같이 사용할 수 있기 때문입니다.

Jasypt 라이브러리

일단 모든 설명은 공식문서와 깃허브에서 가져왔음을 알립니다.

Encrption이라는 키워드로 검색했을 때 Jasypt 라는 라이브러리가 자주 등장했습니다.

Jasypt는 자바에서 암호화를 쉽게 할 수 있도록 도와주는 라이브러리였습니다.

나는 Spring에서 프로젝트가 실행될 때 암호화를 해제하는걸 원했는데 딱 원하던 내용을 찾을 수 있었습니다.

@Bean("jasyptStringEncryptor")
public StringEncryptor stringEncryptor() {
    PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
    SimpleStringPBEConfig config = new SimpleStringPBEConfig();
    config.setPassword("password");
    config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
    config.setKeyObtentionIterations("1000");
    config.setPoolSize("1");
    config.setProviderName("SunJCE");
    config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
    config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
    config.setStringOutputType("base64");
    encryptor.setConfig(config);
    return encryptor;
}

공식 문서에는 이렇게 Bean을 세팅하여 주입하는 식으로 설명이 되어있었습니다.

스크린샷 2021-09-12 오후 8 49 17

이 암호화 Configuration 설명을 보시면 키들이 properties 형식으로 작성이 되어있기에 저희 프로젝트의

yaml 형식으로 바꾸어

jasypt:
  encryptor:
    password: "비밀번호"

를 만들고 타고 들어갔을때의 내부 구현 클래스의 사진을 가져왔습니다.

스크린샷 2021-09-12 오후 8 47 51

properties의 설명은 당연히 jasypt.encryptor의 하위에 소스들을 읽어 들여서
세팅을 해주게 되어있습니다.

이미지를 부분만 캡쳐하여 가져왔기 때문에 보이지는 않지만,

조회해본 결과 password 외에는 전부 기본값이 설정이 되어 적용되어 있음을 확인하였습니다.

ENC() 문자열로 감싸준 이유는 암호화문을 ENC 괄호안으로 넣어주었을 경우

설정해준 jasypt.encryptor.password의 값을 읽은 후 복호화를 진행해줍니다.

저는 아래와 같이 테스트코드를 작성하여 암호를 설정해 암호화를 진행했습니다.

public class JasyptTest {
    @Test
    void jasyptTest() {
        StandardPBEStringEncryptor pbeEnc = new StandardPBEStringEncryptor();
        pbeEnc.setAlgorithm("PBEWithMD5AndDES");
        pbeEnc.setPassword("사용할 암호");

        String clientId = pbeEnc.encrypt("암호화 하려는 아이디");
        String password = pbeEnc.encrypt("암호화 하려는 비밀번호");

        System.out.println(clientId);
        System.out.println(password);
    }
}

고민사항

여기서 암호화를 하는 과정은 알게 되었습니다.

여기서 했던 고민은 결국 이 비밀번호도 어딘가에 저장해야 하는데

어떻게 저장해야 할까?

가 관건이었습니다.

회의를 통해 나온 결론은 모든 암호화는 지금처럼 적용하되, 해당 암호에 대한 설정은

각자의 컴퓨터의 환경변수로 잡아주자 라는 결론으로 모아졌습니다.

그래서 저희는 환경변수로 잡아주었습니다.

저는 맥의 환경이었으므로 이렇게 진행하였습니다.

cd ~
vi .profile/

# vi 에디터 사용하여 쉘 스크립트 작성으로
export JASYPT_PASSWORD="패스워드"
:wq

source ~/.profile

를 해주었습니다.

이 환경변수를 잡는 과정에서 상당히 많은 이슈가 발생했었는데요 😭

일단 저희는 깃허브 CI, CD를 사용하고 있기 때문에

push를 하게 되면 이후의 깃허브 가상 도커 컨테이너에서 빌드를 진행하여 저 부분에 대해서는 환경변수를 넣기 애매했습니다.

그리고

java build -DJASYPT_PASSWORD
java test -DJASYPT_PASSWORD

이런 명령어들 마다 계속 값 세팅이 달라졌기 때문에 하나가 성공하면 하나가 실패하는 그런 케이스가 지속이 되었습니다.

깃허브에서는 어떻게 환경변수를 넣을까 공식문서를 찾아본 결과

env:
      JASYPT_PASSWORD: ${ secrets.JASYPT_PASSWORD } # 중괄호 2개 사용해야함

CI,CD yaml파일에 다음과 같이 추가를 해주면 환경변수로 잡아줄 수가 있었습니다.

jobs:
  build:
    runs-on: ubuntu-latest
    env:
      JASYPT_PASSWORD: ${ secrets.JASYPT_PASSWORD } # 중괄호 2개 사용해야함

secrets는 깃허브 Action 설정에서 전역으로 JASYPT_PASSWORD 라는 키에 저희 암호를 넣어주고 ${} 형식으로 불러올 수가 있습니다.

이렇게 하고 명령어를 써주어 암호화를 진행할 수 있게 되었습니다.

이 부분이 깊게는 알아서 쓰는것은 아니고 단순히 암호화를 하여 소스를 가리는 목적으로만 사용해서

이정도 깊이정도만 학습해도 별 문제없이 쓸수 있을정도의 라이브러리 였기 떄문에 여기까지만

알아보도록 하겠습니다.

정리

팀 프로젝트를 협업하면서 이번 부분에서 보안에 굉장히 많은 시간을 제가 투자하고 있는것 같습니다.

처음 적용 시켜보지만 디버깅과 깊게 조사하면서 배우니까 확실히 제껄로 만들어가는 느낌이 굉장히 좋습니다.

728x90

'Spring' 카테고리의 다른 글

Validaion  (0) 2022.08.09
Filter, Interceptor 정리  (0) 2022.08.07
Spring -> Spring Boot 마이그레이션 2  (0) 2022.08.06
Spring Data JPA  (0) 2022.08.06

+ Recent posts