๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Back-end/JAVA & Spring

[ Spring Boot ] Jasypt: Spring Boot์—์„œ ๊ฐ„๋‹จํ•˜๊ณ  ์•ˆ์ „ํ•œ ์•”ํ˜ธํ™”

 

 

 

 

 

๐ŸŒฑ Spring Boot - Jasypt

 

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ ์ค‘ ๋ฏผ๊ฐํ•œ ์ •๋ณด(์˜ˆ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด, API ํ‚ค, ๋น„๋ฐ€๋ฒˆํ˜ธ ๋“ฑ)๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ์ผ์€ ๋ณด์•ˆ์˜ ํ•ต์‹ฌ ์š”์†Œ์ด๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์ •๋ณด๋ฅผ ํ‰๋ฌธ์œผ๋กœ ์„ค์ • ํŒŒ์ผ์— ์ €์žฅํ•˜๋ฉด ๋ณด์•ˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด **Jasypt(Java Simplified Encryption)**๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. Jasypt๋Š” Spring Boot์™€ ์‰ฝ๊ฒŒ ํ†ตํ•ฉ๋˜์–ด ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™”ํ•˜๊ณ  ์•ˆ์ „ํ•˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ„๋‹จํ•˜๋ฉด์„œ๋„ ๊ฐ•๋ ฅํ•œ ์†”๋ฃจ์…˜์„ ์ œ๊ณตํ•œ๋‹ค. 

 

 

Jasypt

Jasypt(Java Simplified Encryption)์€ Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์•”ํ˜ธํ™” ๋ฐ ๋ณตํ˜ธํ™”๋ฅผ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค๊ณ„๋œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค. ํŠนํžˆ Spring Boot์™€ ํ†ตํ•ฉํ•˜๋ฉด ์„ค์ • ํŒŒ์ผ์— ํฌํ•จ๋œ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์•”ํ˜ธํ™”ํ•œ ์ƒํƒœ๋กœ ์ €์žฅํ•˜๊ณ , ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์‹œ ์ž๋™์œผ๋กœ ๋ณตํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค. 

 

Jasypt์˜ ์ฃผ์š” ํŠน์ง•:

  • AES, PBE ๋“ฑ ๋‹ค์–‘ํ•œ ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ง€์›
  • ์„ค์ • ํŒŒ์ผ์— ํฌํ•จ๋œ ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ ์ž๋™ ๋ณตํ˜ธํ™”
  • ๊ฐ„๋‹จํ•œ ์„ค์ •๊ณผ ์‚ฌ์šฉ๋ฒ•

 

 

Jasypt ์„ค์ •ํ•˜๊ธฐ

์˜์กด์„ฑ ์ถ”๊ฐ€

build.gradle์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•œ ํ›„ ํ”„๋กœ์ ํŠธ ๋นŒ๋“œ 

 

dependencies {
    implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
}

 

 

 

 

Jasypt ์„ค์ • ํด๋ž˜์Šค ์ž‘์„ฑ

 

@Configuration
@Slf4j
public class JasyptConfig {

    @Bean("jasyptStringEncryptor")
    public StringEncryptor stringEncryptor() {

        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();

        // ์•”ํ˜ธํ™” ํ‚ค ์„ค์ •: ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋˜๋Š” ์‹œ์Šคํ…œ ์†์„ฑ์—์„œ ์ฝ์Œ
        String encryptionKey = System.getenv("JASYPT_ENCRYPTOR_PASSWORD");
        if ( StringUtils.isBlank(encryptionKey) ) {
            throw new IllegalStateException("JASYPT_ENCRYPTOR_PASSWORD ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ์„ค์ •๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.");
        }

        // Jasypt ์•”ํ˜ธํ™” ๊ธฐ๋ณธ ์„ค์ •
        config.setPassword(encryptionKey);
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setStringOutputType("base64");

        encryptor.setConfig(config);
        log.info("Jasypt StringEncryptor๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์„ค์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");

        return encryptor;
    }
}

 

 

config.setPassword(encryptionKey)

์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”๋ฅผ ์œ„ํ•œ ๋น„๋ฐ€ ํ‚ค๋ฅผ ์„ค์ •ํ•œ๋‹ค. ์ด ํ‚ค๋Š” ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™”ํ•  ๋•Œ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋™์ผํ•œ ํ‚ค๊ฐ€ ์žˆ์–ด์•ผ ๋ณตํ˜ธํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. 

 

์ค‘์š”์‚ฌํ•ญ:

- ์•ˆ์ „ํ•œ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ์™ธ๋ถ€ ๋น„๋ฐ€ ๊ด€๋ฆฌ ์„œ๋น„์Šค๋ฅผ ์‚ฌ์šฉํ•ด ๊ด€๋ฆฌ

- ์ด ๊ฐ’์€ ์†Œ์Šค ์ฝ”๋“œ์— ์ง์ ‘ ํฌํ•จ x

 

 

 

 

config.setAlgorithm("PBEWithMD5AndDES")

์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ค์ •ํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ PBEWithMD5AndDES๋Š” Password-Based Encryption(PBE) ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ, MD5 ํ•ด์‹ฑ๊ณผ DES(Data Encryption Standard)๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

๊ธฐ๋ณธ๊ฐ’: Jasypt์˜ ๊ธฐ๋ณธ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ PBEWithMD5AndDES

๋‹ค๋ฅธ ์˜ต์…˜: 

- PBEWithSHA256And128BitAES-CDC-BC (๋” ์•ˆ์ „ํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜)

- PBEWithSHA256And192BitAES-CDC-BC

๊ฐ€๋Šฅํ•˜๋ฉด ๋” ๊ฐ•๋ ฅํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜(AES ๊ธฐ๋ฐ˜)์„ ๊ถŒ์žฅํ•œ๋‹ค.

 

 

 

 

config.setKeyObtentionIterations("1000")

์•”ํ˜ธํ™” ํ‚ค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ ์šฉํ•  ํ•ด์‹ฑ์˜ ํšŸ์ˆ˜๋ฅผ ์„ค์ •ํ•œ๋‹ค. ๋ฐ˜๋ณต ํšŸ์ˆ˜๊ฐ€ ๋งŽ์„ ์ˆ˜๋ก ์•”ํ˜ธํ™”๋Š” ๋” ์•ˆ์ „ํ•˜์ง€๋งŒ, ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค. 

 

๊ธฐ๋ณธ๊ฐ’: 1000

์ถ”์ฒœ ๊ฐ’: ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๋ ค๋ฉด 10000 ์ด์ƒ์˜ ๊ฐ’์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. 

์ฃผ์˜: ๋„ˆ๋ฌด ๋†’์€ ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

config.setPoolSize("1")

์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”๋ฅผ ์ฒ˜๋ฆฌํ•  ๋•Œ ์‚ฌ์šฉํ•  ์Šค๋ ˆ๋“œ ํ’€์˜ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•œ๋‹ค.

 

๊ธฐ๋ณธ๊ฐ’: 1

์ถ”์ฒœ ๊ฐ’: ์ผ๋ฐ˜์ ์œผ๋กœ 1๋กœ ์„ค์ •ํ•˜์ง€๋งŒ, ๋†’์€ ํŠธ๋ž˜ํ”ฝ ํ™˜๊ฒฝ์—์„œ๋Š” ๋” ํฐ ๊ฐ’์„ ์„ค์ •ํ•˜์—ฌ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฃผ์˜: ๋„ˆ๋ฌด ํฐ ๊ฐ’์„ ์„ค์ •ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

 config.setProviderName("SunJCE")

์•”ํ˜ธํ™” ์ž‘์—…์— ์‚ฌ์šฉํ•  JCE(Java Cryptography Extension) ์ œ๊ณต์ž๋ฅผ ์ง€์ •ํ•œ๋‹ค. 

 

๊ธฐ๋ณธ๊ฐ’: SunJCE (Java์˜ ๊ธฐ๋ณธ ์ œ๊ณต์ž)

๋‹ค๋ฅธ ์˜ต์…˜:

- BC (Bouncy Castle ์•”ํ˜ธํ™” ์ œ๊ณต์ž)์™€ ๊ฐ™์€ ์™ธ๋ถ€ ์ œ๊ณต์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

- Bouncy Castle์€ ๋” ๋‹น์•ผํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ง€์›ํ•˜๋ฏ€๋กœ ํ•„์š”์— ๋”ฐ๋ผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

 

 

 

 

config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator")

์•”ํ˜ธํ™”์— ์‚ฌ์šฉํ•  Salt(๋‚œ์ˆ˜)๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํด๋ž˜์Šค ์ด๋ฆ„์„ ์„ค์ •ํ•œ๋‹ค. Salt๋Š” ๋™์ผํ•œ ๊ฐ’์ด ์•”ํ˜ธํ™”๋˜๋”๋ผ๋„ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค.

 

๊ธฐ๋ณธ๊ฐ’: RandomSaltGenerator

๋‹ค๋ฅธ ์˜ต์…˜:

- ZeroSaltGenerator: Salt๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ (๋ณด์•ˆ์„ฑ์ด ๋–จ์–ด์ง)

- FixedSaltGenerator: ๊ณ ์ •๋œ Salt ์‚ฌ์šฉ (ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉ)

์ผ๋ฐ˜์ ์œผ๋กœ RandomSaltGenerator๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค.

 

 

 

 

config.setStringOutPutType("base64")

์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋–ค ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅํ• ์ง€ ์„ค์ •ํ•œ๋‹ค.

 

๊ธฐ๋ณธ๊ฐ’: base64 (์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ base64 ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅ. ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ํŒŒ์ผ ์ €์žฅ์‹œ ์œ ์šฉ)

๋‹ค๋ฅธ ์˜ต์…˜:

- hexadecimal: ์•”ํ˜ธํ™”๋œ ๋ฐ์ดํ„ฐ๋ฅผ 16์ง„์ˆ˜ ํ˜•์‹์œผ๋กœ ์ถœ๋ ฅ

 

 

 

 

์•”ํ˜ธํ™” ํ‚ค ์„ค์ •

Jasypt๋Š” ์•”ํ˜ธํ™” ํ‚ค๊ฐ€ ํ•„์š”ํ•˜๋‹ค. ์ด ํ‚ค๋Š” ๋ณด์•ˆ์˜ ํ•ต์‹ฌ์ด๋ฏ€๋กœ, ๋ฐ˜๋“œ์‹œ ์•ˆ์ „ํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ด€๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

 

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋กœ ์„ค์ • (์ถ”์ฒœ)

Window

 

set JASYPT_ENCRYPTOR_PASSWORD=your-secret-key

 

 

Linux/Mac

 

export JASYPT_ENCRYPTOR_PASSWORD=your-secret-key

 

 

๋ช…๋ น์ค„ ์ธ์ˆ˜๋กœ ์ „๋‹ฌ

 

java -Djasypt.encryptor.password=your-secret-key -jar your-app.jar

 

 

 

 

Jasypt ์‚ฌ์šฉํ•œ Datasource ์•”ํ˜ธํ™” ์„ค์ • ์ƒ์„ธ

 

https://euntry.tistory.com/67

 

[ Spring Boot ] Spring Boot์—์„œ Datasource ์•”ํ˜ธํ™”ํ•˜๊ธฐ

๐ŸŒฑ Spring Boot - Datasource ์•”ํ˜ธํ™” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ spring.datasource.url, spring.datasource.username, spring.datasource.password๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ๋ฏผ๊ฐ ์ •๋ณด ์ค‘ ํ•˜๋‚˜์ด๋‹ค. ์ด ์ •๋ณด๊ฐ€ ์™ธ๋ถ€๋กœ ๋…ธ

euntry.tistory.com