Post

Jasypt_encryption

โœ… Background Knowledge

๐Ÿ’ก Jasypt:

Java Simplified Encryption Java library that provides simple APIs for encryption and decryption of data, including hashing.

โœ”๏ธ ํ•ด์‹ฑ์ด๋ž€?

transforming text into charecters using a one-way cryptographic hash function

  • one way cryptographic function
  • results in hash value/hash code
  • irreversable
  • MD5, SHA-1, SHA-256

๐Ÿ†š Encryption

  • eversible cryptographic process
  • encrypts with an algorithm and a key
  • AES, DES, RSA

Hash ๐Ÿ†š Encryption ๐Ÿ†š Encoding

https://www.geeksforgeeks.org/encryption-encoding-hashing/

โœ”๏ธ Salt?

โ€œsaltโ€ is random data that is used as an additional input to a hash function along with the plain text being hashed

  • thanks to salt, we can defend against attacks and add complexity to the hashing process.
  • When hashing a password or any other sensitive data, you can provide a salt along with the data.
  • The salt is then combined with the data before hashing, resulting in a unique hash for each input even if the original data is the same.

โœ”๏ธ ์ธ์ฝ”๋”ฉ?

process of transforming data into a format that is suitable for a particular type of transmission or storage system

  • GOAL: make sure data can be represented and transmitted properly
  • Base64, hexadecimal, URL encoding

๐Ÿ†š Encryption

  • GOAL: protect data, data confidentiality

โœ… Bean์œผ๋กœ Jasypt ์•”ํ˜ธํ™” ์„ค์ •

Jasypt build.gradle ์ถ”๊ฐ€

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// redis -> java๋กœ redis control
    implementation 'redis.clients:jedis:5.1.0'

    //jasypt
    implementation 'com.github.ulisesbocchio:jasypt-spring-boot-starter:3.0.5'
    implementation 'javax.xml.bind:jaxb-api:2.3.1'

    // validation
    implementation 'org.springframework.boot:spring-boot-starter-validation'


    //assertions for testJasyptConfig
    implementation 'org.assertj:assertj-core:3.19.0'
    //test for testJasyptConfig
    implementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'

Jasypt Config

  • ์•„๊นŒ ์ด๋ฉ”์ผ ๋ณด๋‚ผ email Address, ์ƒ์„ฑํ•œ ์•ฑ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ yaml์—์„œ ์•”ํ˜ธํ™”ํ•ด์„œ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•จ
  • Jasypt secret key: ์ด๋ฉ”์ผ ์ฃผ์†Œ, ์•ฑ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋“ฑ์„ ์•”ํ˜ธํ™”ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ
  • ์•”ํ˜ธํ™”ํ•˜๋Š” ๋ฉ”์†Œ๋“œ stringEncryptor
    • ์•”ํ˜ธํ™” ๋น„๋ฐ€๋ฒˆํ˜ธ
    • ์–ด๋–ค ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์“ธ๊ฑด์ง€
    • ๋ฐ˜๋ณตํ•  ํ•ด์‹ฑ ํšŒ์ˆ˜
    • salt ์ƒ์„ฑ ํด๋ž˜์Šค
    • ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹
  • salt ์ƒ์„ฑ ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด default๋กœ: RandomSaltGenerator
  • ๊ณ ์ •๋œ salt ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด StringFixedSaltGenerator๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค
  • ๋‹จ ์ด ๊ฒฝ์šฐ ๋ณตํ˜ธํ™”์‹œ์—๋„ ๊ธฐ์กด์— ์„ค์ •ํ•œ salt ๊ฐ’ ์‚ฌ์šฉํ•ด์•ผ์ง€๋งŒ ๋ณตํ˜ธํ™” ๊ฐ€๋Šฅ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import com.ulisesbocchio.jasyptspringboot.annotation.EnableEncryptableProperties;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableEncryptableProperties
public class JasyptConfig {
    @Value(value= "${jasypt.encryptor.password}")
    private String PASSWORD_KEY;

    @Bean(name= "jasyptStringEncryptor")
    public StringEncryptor stringEncryptor(){
        PooledPBEStringEncryptor encryptor= new PooledPBEStringEncryptor();
        SimpleStringPBEConfig config= new SimpleStringPBEConfig();
        config.setPassword(PASSWORD_KEY);
        config.setAlgorithm("PBEWithMD5AndDES");
        config.setKeyObtentionIterations("1000");  // ๋ฐ˜๋ณตํ•  ํ•ด์‹ฑ ํšŸ์ˆ˜
        config.setPoolSize("1"); // ์•”ํ˜ธํ™” ์ธ์Šคํ„ด์Šค pool
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator"); // salt ์ƒ์„ฑ ํด๋ž˜์Šค
        config.setStringOutputType("base64"); // ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹
        encryptor.setConfig(config);
        return encryptor;
    }

}

application.yaml

PBEWithMD5AndDESย encryption ์ œ๊ณตํ•˜๋Š” ์‚ฌ์ดํŠธ์—์„œ ์•”ํ˜ธํ™”
https://devglan.com/onaline-tools/jasypt-online-encryption-decryption

image


์•”ํ˜ธํ™”ํ•œ email Address, ์ƒ์„ฑํ•œ ์•ฑ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ENC()๋กœ ๊ฐ์‹ธ์„œ ๋„ฃ์–ด๋‘ 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
  data:
    redis:
      host: localhost
      port: 6379

jasypt:
  encryptor:
    password: ${JASYPT_SECRET_KEY} //ํ™˜๊ฒฝ๋ณ€์ˆ˜
    bean: jasyptStringEncryptor

email:
  address: ENC(์•”ํ˜ธํ™”ํ•ด์„œ ์“ฐ๊ธฐ)
  app-password: ENC(์•”ํ˜ธํ™”ํ•ด์„œ ์“ฐ๊ธฐ)



jwtpassword:
  source: ENC(jwtpassword์•”ํ˜ธํ™”ํ•ด์„œ ์“ฐ๊ธฐ)

์™„์„ฑ๋œ yamlํŒŒ์ผ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ๊ฒผ์„ ๊ฒƒ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
server: port:8080

spring:
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher

  autoconfigure: exclude:org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

  datasource:
    username: ENC(dg0o6RGGnI5v2NTvYqiCeA==)
    password: ENC(3S04ny0whtz9bZ4PvLkMuIFXmnRB0pjy)
    driver-class-name: org.mariadb.jdbc.Driver
    #  url: jdbc:mariadb://sohan2.c7suy242wrpp.eu-west-1.rds.amazonaws.com:3306/shopping_mall?useUnicode=true&characterEncoding=UTF-8
    url: jdbc:mariadb://localhost:3306/BackEndProject_2_verSoh?useUnicode=true&characterEncoding=UTF-8

  jpa:
    show-sql: true

  data:
    redis:
      host: localhost
      port: 6379

jasypt:
  encryptor:
    password: ${JASYPT_SECRET_KEY}
    bean: jasyptStringEncryptor

email:
  address: ENC(9FFPzV1CpODhRFqWQPJg6RDj9yuVaV4jnT0FQvc4oE0=)
  app-password: ENC(3ViVckG3lnbAeZWKhkWT06ChwI8rfEazJBqXJL5fBak=)

jwtpassword:
  source: ENC(/CzryCVnQTpLw20DGA4M7ENiN+eg+PDQ)

  logging:
    level: debug

๐Ÿ”ด TroubleShooting

jwtpassword:๋˜ํ•œ ENC()๋กœ ๊ฐ์‹ธ์„œ ์•”ํ˜ธํ™”ํ–ˆ๋”๋‹ˆ, jwtTokenProvider์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๊ณ  error๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
์œ„ yaml์ฒ˜๋Ÿผ ๋ฐ”๊ฟ”์ค„๊ฑฐ๋ฉด, ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ jwtTokenProviderํŒŒ์ผ์—์„œ jwtpassword:๋˜ํ•œ ์ˆ˜์ •ํ•ด ์ฃผ์–ด์•ผ ํ•œ๋‹ค.
yamlํŒŒ์ผ์— ์–ด๋””๋ฅผ ๋ณด๋ฉด ๋˜๋Š”์ง€๋ฅผ ์•Œ๋ ค์ฃผ์–ด์•ผ ํ•จ.
jwtpassword ์˜ source๋ฅผ ๋ณด๋ ด!

1
2
3
4
5
6
7
8
9
10
11
@Component
@RequiredArgsConstructor
public class JwtTokenProvider {
    private final UserDetailsService userDetailsService;
//    @Value("${JWT_SECRET_KEY}") //์ˆ˜์ • ์ „
    @Value("${jwtpassword.source}") //์ˆ˜์ • ํ›„
    private String secretKey;
    private String key;

    //JwtTokenProvider methods...
}

โž• JasyptConfigTest ์—์„œ ์•”ํ˜ธํ™”

๋˜๋Š” JasyptConfigTest ์—์„œ System.out.printlnํ•ด์„œ ์•”ํ˜ธํ™”ํ•ด๋„ ๋œ๋‹ค.
์œ„ ์‚ฌ์ดํŠธ์—์„œ ์•”ํ˜ธํ™”ํ–ˆ์œผ๋ฉด ์ด ํŒŒ์ผ ์—†์–ด๋„ ๋จ.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import org.assertj.core.api.Assertions;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.junit.jupiter.api.Test;

public class JasyptConfigTest {

    @Test
    void jasypt(){
        String url= "db์ฃผ์†Œ";
        String username= "๋„ค์ž„";
        String password= "๋น„๋ฐ€๋ฒˆํ˜ธ";

        String encryptUrl= jasyptEncrypt(url);
        String encryptUsername= jasyptEncrypt(username);
        String encryptPassword= jasyptEncrypt(password);

        System.out.println("encryptUrl : " + encryptUrl);
        System.out.println("encryptUrl : " + encryptUsername);
        System.out.println("encryptPassword : " + encryptPassword);

        Assertions.assertThat(url).isEqualTo(jasyptDecrypt(encryptUrl));
    }

    private String jasyptEncrypt(String input){
        String key= "cesarpoo";
        StandardPBEStringEncryptor encryptor= new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWithMD5AndDES");
        encryptor.setPassword(key);
        return encryptor.encrypt(input);
    }

    private String jasyptDecrypt(String input){
        String key= "cesarpoo";
        StandardPBEStringEncryptor encryptor= new StandardPBEStringEncryptor();
        encryptor.setAlgorithm("PBEWithMD5AndDES");
        encryptor.setPassword(key);
        return encryptor.decrypt(input);
    }


}

โœ… Run redis server on EC2

Redis server install

Screenshot 2024-06-16 at 15 29 10

Screenshot 2024-06-16 at 15 29 28

์„œ๋ฒ„ ์‹œ์ž‘ํ•˜๋Š” ๋ช…๋ น์–ด

1
sudo systemctl start redis

์„œ๋ฒ„ ์ƒํƒœ ํ™•์ธํ•˜๋Š” ๋ช…๋ น์–ด

1
sudo systemctl status redis

redis.conf

  1. Redis.conf์— ๋“ค์–ด๊ฐ€์„œ
1
sudo nano /etc/redis/redis.conf
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ๋ฐ”๊พธ๊ธฐ(์ฐธ๊ณ ์ž๋ฃŒ)
  • protected-mode ๋ฐ”๊พธ๊ธฐ
1
2
protected-mode no

  • ์„œ๋ฒ„ ๋ฐ”๊พธ๊ธฐ
1
bind 0.0.0.0
  1. ๋ฐฉํ™”๋ฒฝ ํ’€์–ด์ฃผ๊ธฐ
1
sudo ufw allow 6379

์„œ๋ฒ„ ์žฌ์‹œ์ž‘ ๋ช…๋ น์–ด

1
sudo systemctl restart redis

ํฌํŠธ 6379 ์—ด๊ธฐ

redis๋Š” ๋ณดํ†ต ํฌํŠธ 6379์—์„œ ์‹คํ–‰๋œ๋‹ค.

1
sudo netstat -tuln | grep 6379

EC2์™€ ์—ฐ๊ฒฐ๋œ redis์„œ๋ฒ„ ์—ฐ๊ฒฐ

1
redis-cli -h  -p 6379 -a 

๐Ÿ’ก ์ฐธ๊ณ 

https://wookgu.tistory.com/26

Redis Config??? ํ•„์š”๊ฐ€ ์—†์—ˆ๋‹คโ€ฆโ€ฆ

๐Ÿ’ก ์ฐธ๊ณ 

1
2
3
4
5
https://velog.io/@jinny-l/spring-jasypt-encrypt-yml-and-store-encryption-key-as-environment-variable


-- ํ•œ์†”์ด ๋ธ”๋กœ๊ทธ
https://boulder-hippodraco-244.notion.site/Email-Spring-Boot-3-2-52fa5aa2f1154691bd7c2a8fea3d89a6
This post is licensed under CC BY 4.0 by the author.