Back-End ์ž‘์—…์‹ค/Spring Framework

[JAVA - Spring Boot] ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™” ๊ธฐ๋Šฅ ๋งŒ๋“ค๊ธฐ

์ฃผ๋‹ˆ์“ฐ๐Ÿง‘‍๐Ÿ’ป 2022. 12. 7. 01:21
728x90
๋ฐ˜์‘ํ˜•




 

๋ฐฑ๊ฒฌ๋ถˆ์—ฌ์ผํƒ€ ์Šคํ”„๋ง ๋ถ€ํŠธ ์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ with JPA:์ด์   ํ”„๋กœ์ ํŠธ๋‹ค!

COUPANG

www.coupang.com

 

 

 

React.js ์Šคํ”„๋ง ๋ถ€ํŠธ AWS๋กœ ๋ฐฐ์šฐ๋Š” ์›น ๊ฐœ๋ฐœ 101:SPA REST API ๊ธฐ๋ฐ˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ

COUPANG

www.coupang.com

 

 

 

์Šคํƒ€ํŠธ ์Šคํ”„๋ง ๋ถ€ํŠธ:์ดˆ๊ธ‰ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ๊ฐ€๋ณ๊ณ  ๋„“์€ ์Šคํ”„๋ง ๋ถ€ํŠธ

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 



 

 

GitHub - junyharang-coding-study/JunyHarang-JAVA-EncryptionDecryption: JAVA์™€ Spring Boot๋ฅผ ํ†ตํ•ด Data๋ฅผ ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”

JAVA์™€ Spring Boot๋ฅผ ํ†ตํ•ด Data๋ฅผ ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™” ํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด์šฉ์„ ๊ณต๋ถ€ํ•ด ๋ณธ ๋‚ด์šฉ์ด์—์š”. - GitHub - junyharang-coding-study/JunyHarang-JAVA-EncryptionDecryption: JAVA์™€ Spring Boot๋ฅผ ํ†ตํ•ด Data๋ฅผ ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™” ํ•  ์ˆ˜ ์žˆ

github.com

 




๐Ÿš€ ์•”ํ˜ธํ™”/๋ณตํ˜ธํ™”

    ๐Ÿ”ฝ ๊ฐœ์š”

        ๐Ÿ“ฆ ์†Œ๊ฐœ

์ฃผ๋‹ˆํ•˜๋ž‘์€ ํ˜„์žฌ ์ง„ํ–‰์ค‘์ธ Side Project์—์„œ ์ด์šฉ์ž์˜ ๊ฐœ์ธ์ •๋ณด ๋“ฑ์„ ์•”ํ˜ธํ™”ํ•˜์—ฌ DB์— ์ €์žฅํ•˜๊ณ , ๊ถŒํ•œ์ด ์žˆ๋Š” ์ด์šฉ์ž ํ˜น์€ ์‚ฌ์šฉ์ž์—๊ฒŒ๋Š” ๋ณตํ˜ธํ™”ํ•˜์—ฌ ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” Logic์„ ๊ตฌํ˜„ํ•˜๊ณ  ์‹ถ์—ˆ์–ด์š”.

์˜ค๋Š˜์€ ๊ทธ ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด Spring Boot๋ฅผ ๊ฐ€์ง€๊ณ  ๋†€์•„ ๋ณด๋ คํ•ฉ๋‹ˆ๋‹ค.

 

 

 

 

        ๐Ÿ“ฆ ์ดˆ๊ธฐ ๊ตฌ์„ฑ

Project ์ƒ์„ฑ

์ตœ์ดˆ Project๋ฅผ ์œ„์™€ ๊ฐ™์ด ์ƒ์„ฑํ•ด ์ค„๊ฒŒ์š”.


์˜์กด์„ฑ ์„ค์ •


์œ„์™€ ๊ฐ™์ด Spring Boot Version๊ณผ ์˜์กด์„ฑ์„ ๊ตฌ์„ฑํ•ด ์ฃผ์—ˆ์–ด์š”.


build.gradle


๊ทธ๋Ÿฐ ๋’ค 22๋ฒˆ์งธ์— jpa ์˜์กด์„ฑ๋„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ์–ด์š”.

# application.yml

server:
  port: 8080

spring:
  datasource:
    url: jdbc:mysql://{DBMS IP}:{PORT}/{DB ์ด๋ฆ„}?serverTimezone=UTC&characterEncoding=UTF-8
    username: {DBMS ๊ณ„์ •๋ช…}
    password: {๋น„๋ฐ€๋ฒˆํ˜ธ}
    driver-class-name: com.mysql.cj.jdbc.Driver

  jpa:
    hibernate:
      ddl-auto: create
      show_sql: true
      format_sql: true
      use_sql_comments: true
      dialect: org.hibernate.dialect.MySQL5InnoDBDialect

  h2:
    console:
      enabled: true


application.yml์€ ์œ„์™€ ๊ฐ™์ด ์„ค์ •ํ•˜์—ฌ DB๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

 

 

 

    ๐Ÿ”ฝ  ์•”/๋ณตํ˜ธํ™” Class

        ๐Ÿ“ฆ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๋ณธ๊ฒฉ์ ์œผ๋กœ ์•” / ๋ณตํ˜ธํ™” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•  Class๋ฅผ ๋งŒ๋“ค์–ด ์ค„๊ฒŒ์š”.

package com.junyharang.endecrypttest.common.constant.endecryption;

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.Locale;

public class DataEnDecryption {

    public static String base64Encoder(String value) {
        byte[] byteKey = value.getBytes();
        return Base64.getEncoder().encodeToString(byteKey);
    }

    public static String dataEnDecrypt(String cipherKey, String data, int cipherMode) {

        String result = null;

        try {
            Cipher cipher = Cipher.getInstance("AES");

            byte[] initializationVector = new byte[16];
            int index = 0;

            for (byte b : cipherKey.getBytes(StandardCharsets.UTF_8)) {
                initializationVector[index++ % 16] ^= b;
            }

            SecretKeySpec keySpec = new SecretKeySpec(initializationVector, "AES");
            cipher.init(cipherMode, keySpec);

            if (cipherMode == Cipher.DECRYPT_MODE) {
                result = new String(cipher.doFinal(Hex.decodeHex(data)), StandardCharsets.UTF_8);
            } else if (cipherMode == Cipher.ENCRYPT_MODE) {
                result = new String(Hex.encodeHex(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)))).toUpperCase(Locale.ROOT);
            } else {

            }
        } catch (NoSuchAlgorithmException |
                 NoSuchPaddingException |
                 DecoderException |
                 IllegalBlockSizeException |
                 BadPaddingException |
                 InvalidKeyException error) {

            error.printStackTrace();
        }
        return result;
    }
}
๋ฐ˜์‘ํ˜•


์ „์ฒด ์ฃผ๋‹ˆํ•˜๋ž‘์ด ์ž‘์„ฑํ•œ Code๋Š” ์œ„์™€ ๊ฐ™์•„์š”.

ํ•˜๋‚˜ํ•˜๋‚˜ ๋œฏ์–ด๋ณด๋ฉด์„œ ๋ถ„์„ํ•ด ๋ณผ๊ฒŒ์š”.

DataEnDecryption 17 ~ 22๋ฒˆ์งธ ์ค„

์ตœ์ดˆ base64Endocer๋ผ๋Š” Method๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.
์ด Method๋Š” ์–ด๋–ค ๊ฐ’์„ ๋ฐ›๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น ๊ฐ’์„ Base64๋กœ Encoder ํ•ด์ฃผ๋Š” Method์—์š”.


๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ
Base64๋ž€?
byte ํ˜•์‹์œผ๋กœ ๋œ Binary Data๋ฅผ Program ๊ฐ„์— ๋‹ค๋ฃจ๊ธฐ ํŽธํ•œ ascii Code๋กœ ์ด๋ค„์ง„ Data.

์ปดํ“จํ„ฐ ๋ถ„์•ผ์—์„œ ์“ฐ์ด๋Š” Base 64 (๋ฒ ์ด์Šค ์œก์‹ญ์‚ฌ)๋ž€ 8๋น„ํŠธ ์ด์ง„ ๋ฐ์ดํ„ฐ(์˜ˆ๋ฅผ ๋“ค์–ด ์‹คํ–‰ ํŒŒ์ผ์ด๋‚˜, ZIP ํŒŒ์ผ ๋“ฑ)๋ฅผ ๋ฌธ์ž ์ฝ”๋“œ์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๋Š” ๊ณตํ†ต ASCII ์˜์—ญ์˜ ๋ฌธ์ž๋“ค๋กœ๋งŒ ์ด๋ฃจ์–ด์ง„ ์ผ๋ จ์˜ ๋ฌธ์ž์—ด๋กœ ๋ฐ”๊พธ๋Š” ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐœ๋…์ด๋‹ค.

์›๋ž˜ Base 64๋ฅผ ๊ธ€์ž ๊ทธ๋Œ€๋กœ ๋ฒˆ์—ญํ•˜์—ฌ ๋ณด๋ฉด 64์ง„๋ฒ•์ด๋ž€ ๋œป์ด๋‹ค. ํŠน๋ณ„ํžˆ 64์ง„๋ฒ•์ด ์ปดํ“จํ„ฐ์—์„œ ํฅ๋ฏธ๋กœ์šด ๊ฒƒ์€, 64๊ฐ€ 2์˜ ์ œ๊ณฑ์ˆ˜(64 = 26)์ด๋ฉฐ, 2์˜ ์ œ๊ณฑ์ˆ˜๋“ค์— ๊ธฐ๋ฐ˜ํ•œ ์ง„๋ฒ•๋“ค ์ค‘์—์„œ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ASCII ๋ฌธ์ž๋“ค์„ ์จ์„œ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ํฐ ์ง„๋ฒ•์ด๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ฆ‰, ๋‹ค์Œ ์ œ๊ณฑ์ˆ˜์ธ 128์ง„๋ฒ•์—๋Š” 128๊ฐœ์˜ ๊ธฐํ˜ธ๊ฐ€ ํ•„์š”ํ•œ๋ฐ ํ™”๋ฉด์— ํ‘œ์‹œ๋˜๋Š” ASCII ๋ฌธ์ž๋“ค์€ 128๊ฐœ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค.

๊ทธ๋Ÿฐ ๊นŒ๋‹ญ์— ์ด ์ธ์ฝ”๋”ฉ์€ ์ „์ž ๋ฉ”์ผ์„ ํ†ตํ•œ ์ด์ง„ ๋ฐ์ดํ„ฐ ์ „์†ก ๋“ฑ์— ๋งŽ์ด ์“ฐ์ด๊ณ  ์žˆ๋‹ค. Base 64์—๋Š” ์–ด๋–ค ๋ฌธ์ž์™€ ๊ธฐํ˜ธ๋ฅผ ์“ฐ๋Š๋ƒ์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ ๋ณ€์ข…์ด ์žˆ์ง€๋งŒ, ์ž˜ ์•Œ๋ ค์ง„ ๊ฒƒ์€ ๋ชจ๋‘ ์ฒ˜์Œ 62๊ฐœ๋Š” ์•ŒํŒŒ๋ฒณ A-Z, a-z์™€ 0-9๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ ๋งˆ์ง€๋ง‰ ๋‘ ๊ฐœ๋ฅผ ์–ด๋–ค ๊ธฐํ˜ธ๋ฅผ ์“ฐ๋Š๋ƒ์˜ ์ฐจ์ด๋งŒ ์žˆ๋‹ค.

์ถœ์ฒ˜ : https://ko.wikipedia.org/wiki/%EB%B2%A0%EC%9D%B4%EC%8A%A464

 




์œ„์™€ ๊ฐ™์ด Value๊ฐ€ ๋“ค์–ด์™”์–ด์š”.

.getBytes()๋Š” ๋ฌธ์ž์—ด(String)์„ Byte Code๋กœ Encoding ํ•ด์ฃผ๋Š” Method์ด๊ณ ,
์ด๊ฑธ byte ๋ฐฐ์—ด๋กœ ํ•˜๋‚˜ํ•˜๋‚˜ ๋‚˜๋ˆ„์–ด์„œ ๋ณ€ํ™˜์„ ํ•ด์ฃผ๋Š” Method์—์š”.

์œ„์™€ ๊ฐ™์ด getBytes() ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ผ€๋ฆญํ„ฐ ์…‹์„ ๋„˜๊ธฐ์ง€ ์•Š์œผ๋ฉด ์ด์šฉ์ž Platform์— ๊ธฐ๋ณธ Charset์œผ๋กœ Encoding ๋˜์š”.



์ฆ‰, Byte์˜ ์‹œํ€€์Šค๋กœ Encoding ํ•˜๊ณ , ์ƒˆ๋กœ์šด Byte Array์— ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋„๋ก ํ•ด์š”.

์ด ๋ฌธ์ž์—ด์ด Default Charset์œผ๋กœ Encoding ํ•  ์ˆ˜ ์—†๋Š” ๊ฒฝ์šฐ ์ด Method์˜ ๋™์ž‘์€ ์ง€์ •๋˜์ง€ ์•Š์•„์š”.



์ตœ์ข…์ ์œผ๋กœ Base64๋กœ Encoding๋˜์–ด ๋ฐ˜ํ™˜๋œ ๊ฐ’์€ ์œ„์™€ ๊ฐ™์•„์š”.

์ด Method๋ฅผ ๋งŒ๋“  ์ด์œ ๋Š” ์•„๋ž˜ ๊ตฌํ˜„๋œ ๊ธฐ๋Šฅ ๊ฐ€์ง€๊ณ  ๋†€๊ธฐ๋ฅผ ๋ณด์‹œ๋ฉด ๋” ์ž์„ธํžˆ ์ดํ•ด๊ฐ€ ๋˜์‹ค๊ฑฐ์—์š”.
์ฃผ๋‹ˆํ•˜๋ž‘์€ ์•”ํ˜ธํ™” / ๋ณตํ˜ธํ™” Logic์„ ๋งŒ๋“ค๋ฉด์„œ Key๊ฐ€ ๋  ๊ฐ’์ด ๊ณต๊ฐœ ๋˜์ง€ ์•Š์•˜์œผ๋ฉด ์ข‹๊ฒ ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์–ด์š”.

๋ฌผ๋ก  ์ง€๊ธˆ Logic๋„ ์™„์ „ํžˆ ๋น„๊ณต๊ฐœ๋Š” ์•„๋‹ˆ์ง€๋งŒ, ๋งค๋ฒˆ ๊ฒŒ์‹œ๋ฌผ์ด ์ž‘์„ฑ๋  ๋•Œ ๋งˆ๋‹ค, ๊ฒŒ์‹œ๋ฌผ ์ œ๋ชฉ์„ ํ†ตํ•ด Base64๋กœ
Encodingํ•˜์—ฌ ์•”ํ˜ธํ™” Key์— ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ํ•˜๋‚˜๋ฅผ ์ •ํ•ด์„œ ๊ณ„์† Key๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์•ˆ์ „ํ•  ๊ฒƒ์ด๋ผ๊ณ  ํŒ๋‹จํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋งŒ๋“  Method์—์š”.


dataEnDecrypt()

728x90


์ด ๋ถ€๋ถ„์ด ๋ณธ๊ฒฉ์ ์ธ ์•”ํ˜ธํ™” / ๋ณตํ˜ธํ™” ์ฒ˜๋ฆฌํ•˜๋Š” Method์—์š”.

์ตœ์ดˆ ๋งค๊ฐœ ๋ณ€์ˆ˜์—์„œ cipherKey๋Š” AES๋กœ ์•”ํ˜ธํ™” ํ•  ๋•Œ ์‚ฌ์šฉ๋  Key ๊ฐ’์„ ๋ฐ›๊ธฐ ์œ„ํ•จ์ด๊ณ ,
data๋Š” ์‹ค์ œ ์•”/๋ณตํ˜ธํ™” ํ•  ๋‚ด์šฉ์„ ๋ฐ›๋Š” ๊ฒƒ์ด๋ฉฐ, cipherMode์˜ ๊ฒฝ์šฐ 1์ด ๋“ค์–ด์˜ค๋ฉด ์•”ํ˜ธํ™” 2๊ฐ€ ๋“ค์–ด์˜ค๋ฉด
๋ณตํ˜ธํ™” Logic์„ ์ฒ˜๋ฆฌ ํ•˜๊ธฐ ์œ„ํ•ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๊ฐ’์„ ๋ฐ›๋Š” ๊ฒƒ์ด์—์š”.

Cipher๋Š” ์•”ํ˜ธํ™” ๊ถŒํ•œ์ด ์žˆ๋Š” ์‚ฌ์šฉ์ž๋งŒ Message๋ฅผ ์ดํ•ดํ•˜๊ฑฐ๋‚˜,
์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก Message๋ฅผ Encodingํ•˜๋Š” ๊ณผ์ •์ด์—์š”.

Cipher Class๋Š” ์•” / ๋ณตํ˜ธํ™” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ณ , JCE Framework์˜ ํ•ต์‹ฌ ๊ตฌ์„ฑ์ด์—์š”.
๋˜ํ•œ, Java Cryptography Extension(JCE)๋Š” JAVA ๋ณด์•ˆ ๊ธฐ๋Šฅ์˜ ํ•ต์‹ฌ์„ ๋‹ด๋‹นํ•˜๋Š” JAVA Cryptography Architectur(JCA)์˜ ์ผ๋ถ€๋ถ„์ด๋ฉฐ, Application Data ์•”ํ˜ธํ™”, ๋ณตํ˜ธํ™” ๊ทธ๋ฆฌ๊ณ  ๊ฐœ์ธ Data Hashing์„ ์ œ๊ณตํ•ด์š”.

30๋ฒˆ์ค„์— Cipher ๊ฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šคํ™” ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” static getInstance()๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•˜๊ณ , ์ด ๋•Œ, ํฌ๋งํ•˜๋Š” ์•”ํ˜ธํ™” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ด๋ฆ„์„ ์ „๋‹ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์„ ํƒ์ ์œผ๋กœ provider์˜ ์ด๋ฆ„์„ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

AES ๋ณ€ํ™˜์€ getInstance Method์— Cipher ๊ฐ์ฒด๋ฅผ AES ์•”ํ˜ธํ™”ํ•˜๋ผ๊ณ  ์š”์ฒญํ•˜๋Š” ๊ฒƒ์ด์—์š”.


๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ
Java์—์„œ secretKey์˜ ๊ธธ์ด๊ฐ€ 32bit๋ผ๋ฉด AES-256, 24bit๋ฉด AES-192, 16bit์˜ ๊ฒฝ์šฐ AES-128๋กœ ์•”ํ˜ธํ™”

 

32๋ฒˆ์งธ ์ค„๋ถ€ํ„ฐ 33๋ฒˆ์งธ ์ค„์€ byte Array 16๊ฐœ์งœ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ด์„œ IV(Inialization Vetor, ์ดˆ๊ธฐํ™” ๋ฒกํ„ฐ)๋ฅผ ๋งŒ๋“ค์–ด ์ค„ ์ค€๋น„๋ฅผ
ํ•˜๊ณ , ๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฆฌ๊ธฐ ์œ„ํ•ด Index ๋ฒˆํ˜ธ๋ฅผ ๋‹ด์„ ๋ณ€์ˆ˜๋ฅผ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ์—ˆ์–ด์š”.



            for (byte b : cipherKey.getBytes(StandardCharsets.UTF_8)) {
                initializationVector[index++ % 16] ^= b;
            }


35 ~ 37๋ฒˆ์งธ ์ค„์— ๋ฐ˜๋ณต๋ฌธ์„ ๋ณด๋ฉด ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ์•”ํ˜ธํ™”๋ฅผ ์œ„ํ•œ Key๊ฐ’์„ byte Array๋กœ ๋ณ€ํ™˜์„ ํ•˜๋Š”๋ฐ, UTF-8 ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ํ•˜๋‚˜ํ•˜๋‚˜ ๋ฐ˜๋ณต์„ ํ•  ๋•Œ ๋งˆ๋‹ค byte b ๋ณ€์ˆ˜์— ๋‹ด๊ฒจ ๋ฐ˜๋ณต๋ฌธ์ด ๋Œ๋„๋ก ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

 

int a = 5;
System.out.prinln(a ^= 3);


// ์ถœ๋ ฅ๊ฐ’ : 00000000000000000000000000000011



๊ทธ๋Ÿฐ ๋’ค initializationVector์— index ๋ณ€์ˆ˜์— 16์„ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€ ๊ฐ’์— 1์„ ๋”ํ•œ ๋ฒˆ์งธ ๊ฐ’์„ ๋น„ํŠธ ๋‹จ์œ„ XOR ํ• ๋‹น ์—ฐ์‚ฐ์ž๋กœ ์ด์ง„ ๊ฐ’์œผ๋กœ ๋‚˜์˜ค๋„๋ก ํ•ด์ฃผ์—ˆ์–ด์š”. ์ฆ‰, ์–‘์ชฝ ์˜คํผ๋žœ๋“œ์— ๋Œ€ํ•ด Bit ๋‹จ์œ„ XOR ์—ฐ์‚ฐ์„ ์‹คํ–‰ํ•˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฅผ initializationVector์— index ๋ณ€์ˆ˜์— 16์„ ๋‚˜๋ˆˆ ๋‚˜๋จธ์ง€ ๊ฐ’์— 1์„ ๋”ํ•œ ๋ฒˆ์งธ ๊ฐ’์— ๋„ฃ๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.



            SecretKeySpec keySpec = new SecretKeySpec(initializationVector, "AES");
            cipher.init(cipherMode, keySpec);


๊ทธ๋Ÿฐ ๋’ค SecretKeySpec ์ƒ์„ฑ์ž์— IV๊ฐ’๊ณผ ์•”ํ˜ธํ™” ๋ฐฉ์‹์„ ์„ ํƒํ•  ๋ฌธ์ž์—ด์„ ๋„ฃ์–ด Key Spec์„ ์ •ํ•œ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์—ˆ์–ด์š”.

Key Interface๋Š” ์•”ํ˜ธํ™” ์ž‘์—…๋“ค์„ ์œ„ํ•œ Key๋ฅผ ๋‚˜ํƒ€๋‚ด์š”. Keys๋Š” Encoding๋œ Key, Key์˜ Encoding Format, ์•”ํ˜ธํ™” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํฌํ•จํ•˜๋Š” ๋ถˆํˆฌ๋ช…ํ•œ ์ปจํ…Œ์ด๋„ˆ์—์š”.

Key๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ Key Factory๋ฅผ ์‚ฌ์šฉํ•˜๋Š” key generators, certificates, ๋˜๋Š” key specifications๋ฅผ ํ†ตํ•ด ํš๋“ํ•  ์ˆ˜ ์žˆ์–ด์š”. ๊ทธ๋ž˜์„œ ์ฃผ๋‹ˆํ•˜๋ž‘์€ initializationVector๋ฅผ ํ†ตํ•ด ์–‘๋ฐฉํ–ฅ Key๋ฅผ ์ƒ์„ฑํ•ด ์ค€ ๊ฒƒ์ด์—์š”.

Cipher๊ฐ์ฒด๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋ฉด์„œ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ž…๋ ฅ ๋ฐ›์€ Mode (1 = ์•”ํ˜ธํ™”, 2 = ๋ณตํ˜ธํ™”)๋ฅผ ๋ฐ›๊ณ ,
keySpec์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.

๐Ÿ’ก ์ฐธ๊ณ  ์‚ฌํ•ญ
Cipher ์ดˆ๊ธฐํ™”(Initalizaion)

Cipher ๊ฐ์ฒด ์ดˆ๊ธฐํ™”๋ฅผ ์œ„ํ•ด Key ํ˜น์€ ์ฆ๋ช…์„œ(Certificate) ๊ทธ๋ฆฌ๊ณ , Chpher ๋™์ž‘ Mode๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” opmode์™€ ํ•จ๊ป˜ init() Method ํ˜ธ์ถœ.

์„ ํƒ์ ์œผ๋กœ Random๊ณผ ๊ด€๋ จ๋œ Source๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ€์žฅ ๋†’์€ ์šฐ์„  ์ˆœ์œ„๋กœ ์„ค์น˜๋œ Provider์˜ SecureRandom ๊ตฌํ˜„ ์‚ฌ์šฉ.

์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณ„ ๋งค๊ฐœ ๋ณ€์ˆ˜ Set์„ ์„ ํƒ์ ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด IvParameterSpec์„ ์ „๋‹ฌํ•˜์—ฌ ์ดˆ๊ธฐํ™” ๋ฐฑํ„ฐ ์ง€์ • ๊ฐ€๋Šฅ.

์ด์šฉ ๊ฐ€๋Šฅ Cipher ๋™์ž‘ Mode
โˆ™ ENCRYPT_MODE : cipher ๊ฐ์ฒด๋ฅผ ์•”ํ˜ธํ™” Mode๋กœ ์ดˆ๊ธฐํ™”
โˆ™ DECRYPT_MODE: cipher ๊ฐ์ฒด๋ฅผ ๋ณตํ˜ธํ™” Mode๋กœ ์ดˆ๊ธฐํ™”
โˆ™ WRAP_MODE: cipher ๊ฐ์ฒด๋ฅผ key-wrapping Mode ์ดˆ๊ธฐํ™”
โˆ™ UNWRAP_MODE: cipher ๊ฐ์ฒด๋ฅผ key-unwrapping Mode ์ดˆ๊ธฐํ™”


๋งŒ์•ฝ ๊ณต๊ธ‰๋œ Key๊ฐ€ ๊ธธ์ด๋‚˜, Encoding์ด ์ ํ•ฉํ•˜์ง€ ๋ชปํ•ด cipher ์ดˆ๊ธฐํ™”์— ๋ถ€์ ํ•ฉํ•˜๋‹ค๋ฉด init()์€
InvalidKeyException์„ ํ„ฐํŠธ๋ฆฌ๊ฒŒ ๋˜์š”.

๋˜ํ•œ, Cipher๊ฐ€ Key์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํŠน์ • ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋งค๊ฐœ ๋ณ€์ˆ˜๊ฐ€ ํ•„์š”ํ•˜๊ฑฐ๋‚˜, Key๊ฐ€ ํ—ˆ์šฉ ๊ฐ€๋Šฅํ•œ ์ตœ๋Œ€ ํฌ๊ธฐ(์„ค์ •๋œ JCE ๊ด€ํ•  ์ •์ฑ… File์— ๋”ฐ๋ผ ๊ฒฐ์ •)๋ฅผ ์ดˆ๊ณผํ•  ๊ฒฝ์šฐ์—๋„
Exception์ด ํ„ฐ์ง€๊ฒŒ ๋˜์š”.

๋งŒ์•ฝ ์ธ์ฆ์„œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์•„๋ž˜ ์˜ˆ์ œ์ฒ˜๋Ÿผ ํ•  ์ˆ˜ ์žˆ์–ด์š”.

public byte[] encryptMessage(byte[] message, Certificate certificate) throws InvalidKeyException, NoSuchPaddingException, NoSuchAlgorithmException {
    
    Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
    cipher.init(Cipher.ENCRYPT_MODE, certificate);
    
    //...
}


Cipher ๊ฐ์ฒด๋Š” Data ์•”ํ˜ธํ™”๋ฅผ ์œ„ํ•ด getPublicKey()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ธ์ฆ์„œ(certificate)๋กœ ๋ถ€ํ„ฐ
๊ณต์šฉํ‚ค๋ฅผ ์–ป๊ฒŒ ๋˜๋Š” ๋ฐฉ์‹์ด์—์š”.






40๋ฒˆ์งธ ์ค„ Debuging





if (cipherMode == Cipher.DECRYPT_MODE) {
    result = new String(cipher.doFinal(Hex.decodeHex(data)), StandardCharsets.UTF_8);
} else if (cipherMode == Cipher.ENCRYPT_MODE) {
    result = new String(Hex.encodeHex(cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)))).toUpperCase(Locale.ROOT);
} else {
    throw new PropertyValueException("์•”/๋ณตํ˜ธํ™” Mode ๋ณ€์ˆ˜๊ฐ’์ด ์ž˜๋ชป ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.", "DataEnDecryption.dataEnDecrypt(int cipherMode)", Integer.toString(cipherMode));
}


๊ทธ๋Ÿฐ ๋’ค ์œ„์™€ ๊ฐ™์ด 42 ~ 48๋ฒˆ์งธ ์ค„์— if๋ฌธ์„ ํ†ตํ•ด ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ
cipherMode ๋ณ€์ˆ˜ ๊ฐ’์ด 1์ธ์ง€ 2์ธ์ง€ ๊ทธ ์™ธ ๊ฐ’์ธ์ง€๋ฅผ ํ™•์ธํ•˜๊ณ  ์žˆ์–ด์š”.

๋งŒ์•ฝ 1์ด๋ผ๋ฉด ์•”ํ˜ธํ™” Logic์„ ์ˆ˜ํ–‰ํ•˜๋Š” else if๋ฌธ์„ ํƒ€๊ฒŒ ๋  ๊ฒƒ์ด๊ณ , ๋ณตํ˜ธํ™”๋ผ๋ฉด if๋ฌธ์„ ํƒ€๊ฒŒ ๋  ๊ฒƒ์ด์—์š”.

๊ทธ ์™ธ์— ๊ฐ’์ด ๋“ค์–ด์˜จ๋‹ค๋ฉด PropertyValueExeception์ด ํ„ฐ์ง€๋ฉด์„œ ์œ„์™€ ๊ฐ™์ด
์–ด๋–ค ๊ฒƒ์ด ์ž˜๋ชป๋˜์—ˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

๋ณตํ˜ธํ™” Logic์„ ํƒ€๊ฒŒ ๋˜๋ฉด ์–ด๋–ค์ผ์ด ๋ฒŒ์–ด์งˆ๊นŒ์š”?

๋จผ์ € String ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋Š”๋ฐ, ์ด ๊ณณ์— doFinal()์„ ํ†ตํ•ด ์•”ํ˜ธํ™” ๋˜๋Š” ๋ณตํ˜ธํ™” Logic์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด์š”. doFinal()์€ ์•”ํ˜ธํ™” ๋˜๋Š” ๋ณตํ˜ธํ™”๋œ Message๋ฅผ ํฌํ•จํ•œ byte Array๋ฅผ ๋ฐ˜ํ™˜ํ•ด ์ฃผ๋Š” ์นœ๊ตฌ์—์š”.

๊ทธ๋ž˜์„œ ํ•ด๋‹น Method ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ ์•”ํ˜ธํ™”ํ•  Message๊ฐ’์„ byte Array ํ˜•์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋˜ UTF-8 ํ˜•์‹์œผ๋กœ ๋ณ€ํ™˜๋˜๊ฒŒ ํ•œ ๋’ค toUpperCase()๋กœ ๋ฌธ์ž์—ด ๋ชจ๋‘๋ฅผ ๋Œ€๋ฌธ์ž๋กœ ๋ณ€๊ฒฝํ•˜๊ฒŒ ํ•ด Root Locale ์ฆ‰, ROOT Locale์€ ์–ธ์–ด, ๋‚˜๋ผ ๋ฐ ๋ณ€ํ˜•์ด Empty์˜ ์บ๋ฆญํ„ฐ Line์ธ ๊ฒƒ ๊ฐ™์€ Locale์ธ๋ฐ, ์ด๊ฒƒ์€ ๋ชจ๋“  Locale์˜ ๊ธฐ์ € Locale๋กœ ๊ฐ„์ฃผ๋˜์–ด Locale์— ์˜์กดํ•˜๋Š” Operation ์–ธ์–ด/๊ตญ๊ฐ€์˜ ์ค‘๋ฆฝ์  Locale๋กœ์จ ์ด์šฉ๋˜๋Š”๋ฐ, ์ด๊ฒƒ์€ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•ด ์ค€ ๋’ค ๋ฐ˜ํ™˜๋œ ๊ฐ’์„

org.apache.commons.codec.binary.Hex๋ฅผ ์ด์šฉํ•˜์—ฌ Hex Encode๋ฅผ ํ•ด์ฃผ๋Š”๋ฐ,
์ด๊ฒƒ์„ ํ†ตํ•ด Hex ์ฆ‰, 16์ง„์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ํ•ด ์ฃผ์—ˆ์–ด์š”.

์•”ํ˜ธํ™” Logic์„ ์ˆ˜ํ–‰ํ•œ ๋’ค ๋ฐ˜ํ™˜๊ฐ’


๊ฒฐ๊ตญ ์œ„์™€ ๊ฐ™์€ ๊ฐ’์ด ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒƒ์ด์—์š”.


๊ทธ๋Ÿผ ๋ณตํ˜ธํ™” Logic์„ ํƒ€๊ฒŒ ๋˜๋ฉด ์–ด๋–ค์ผ์ด ๋ฐœ์ƒํ• ๊นŒ์š”?

์ตœ์ดˆ doFinal()์„ ํ†ตํ•ด ๋ณตํ˜ธํ™”๋œ Message๋ฅผ ํฌํ•จํ•œ byte Array๋ฅผ ๋ฐ˜ํ™˜๋ฐ›์•„ result ๋ณ€์ˆ˜์— ๋„ฃ์„๊ฑด๋ฐ,
doFinal() ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ Hex.encodeHex()๋กœ 16์ง„์ˆ˜ ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ ๋ณตํ˜ธํ™”ํ•˜๋ฉด์„œ
UTF-8 ํ˜•์‹์œผ๋กœ ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•ด ์ฃผ์—ˆ์–ด์š”.



์œ„์™€ ๊ฐ™์ด ์•”ํ˜ธํ™”๋œ Data๊ฐ€ ์ž…๋ ฅ์ด ๋˜๋ฉด 


ํ•ด๋‹น Logic์„ ํ†ตํ•ด ๋ณตํ˜ธํ™”๊ฐ€ ๋˜๋Š” ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.








    ๐Ÿ”ฝ  Test

        ๐Ÿ“ฆ ๊ตฌํ˜„๋œ ๊ธฐ๋Šฅ ๊ฐ€์ง€๊ณ  ๋†€๊ธฐ

ํ•ด๋‹น ๋‚ด์šฉ์— ๋Œ€ํ•œ Code๋Š” ์ด ๊ณณ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์œผ์‹œ๋„๋ก ์ค€๋น„ํ•ด ๋‘์—ˆ์–ด์š”.


BoardServiceImpl.java - 28 ~ 51๋ฒˆ์งธ ์ค„


์ตœ์ดˆ ์ฃผ๋‹ˆํ•˜๋ž‘์€ ๊ฒŒ์‹œ๋ฌผ ์ž‘์„ฑ Method๋ฅผ ๋งŒ๋“ค์–ด ์ฃผ์—ˆ์–ด์š”.

38๋ฒˆ์งธ ์ค„์— ๋ณด๋ฉด ์œ„์—์„œ ๋งŒ๋“  DataEnDecryption ๊ฐ์ฒด์•ˆ์— base64Encodr()๋ฅผ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, ๊ทธ ๋•Œ ReqeustDTO๋กœ ์ „๋‹ฌ๋œ ๊ฒŒ์‹œ๋ฌผ ์ œ๋ชฉ์„ ๋„ฃ์–ด ์ „๋‹ฌํ•˜์—ฌ ํ•ด๋‹น ๊ฒŒ์‹œ๊ธ€ ์ œ๋ชฉ์„ base64๋กœ Encodingํ•œ ๊ฐ’์„ cipherKey ๋ณ€์ˆ˜์— ๋‹ด๋„๋ก ํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค ํ•ด๋‹น DTO ๊ฐ’์„ Data Base์— ๋„ฃ์–ด์ฃผ๊ธฐ ์œ„ํ•ด Entity์˜ Build Pattern์„ ์ด์šฉํ•˜์—ฌ ์ œ๋ชฉ์€ DTO์˜ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๊บผ๋‚ด ์ „๋‹ฌํ•˜์—ฌ ์ฃผ์—ˆ๊ณ , ๋‚ด์šฉ์€ DataEnDecryption ๊ฐ์ฒด์— dataEnDecrypt()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์•”ํ˜ธํ™” ์ €์žฅ์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก Logic์„ ๊ตฌํ˜„ํ•˜์˜€์–ด์š”.

์ฒซ๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” ์•”ํ˜ธํ™” Key๊ฐ€ ๋  ๊ฐ’์œผ๋กœ 38๋ฒˆ์งธ ์ค„์—์„œ ๋งŒ๋“  Base64 ํ˜•์‹์œผ๋กœ Encoding๋œ ์ œ๋ชฉ์„ ์ „๋‹ฌํ•˜์—ฌ ์ฃผ๊ณ , ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์•”ํ˜ธํ™”ํ•  Message
์ฆ‰, DTO์— ๋‹ด๊ธด ๋‚ด์šฉ ๊ฐ’์„ ์ „๋‹ฌํ•˜์—ฌ ์ค€ ๋’ค ๋งˆ์ง€๋ง‰์œผ๋กœ
์•”, ๋ณตํ˜ธํ™” ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•˜๊ฒŒ ๋  cipherMode ๊ฐ’์„ 1๋กœ ํ•˜์—ฌ ์ „๋‹ฌํ•˜์—ฌ ์ฃผ๊ณ ,
์ด๋ฅผ JPA Repository๋ฅผ ํ†ตํ•ด ์ €์žฅ๋œ ๋’ค ํ•ด๋‹น ID๋ฅผ ๋ฐ˜ํ™˜ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•˜์˜€์–ด์š”.

Swagger๋ฅผ ํ†ตํ•œ ๊ฒŒ์‹œ๊ธ€ ์ž‘์„ฑ


์œ„์™€ ๊ฐ™์ด ์ •์ƒ์ ์œผ๋กœ ๋“ฑ๋ก ์„ฑ๊ณต์„ ํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์–ด์š”.

test_board Table


DataBase์—๋„ ์ œ๋ชฉ์€ ํ‰๋ฌธ ์ €์žฅ ๋˜์—ˆ์ง€๋งŒ, ๋‚ด์šฉ์€ ์•”ํ˜ธํ™” ๋˜์„œ ์ €์žฅ๋œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์–ด์š”.



BoardServiceImpl.java - 63 ~ 88๋ฒˆ์งธ ์ค„

 

BoardServiceImpl.java - 133 ~ 138๋ฒˆ์งธ ์ค„


๋‹ค์Œ์œผ๋กœ๋Š” ๋ณตํ˜ธํ™” Logic์„ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์„ธ ๋ณด๊ธฐ ๊ธฐ๋Šฅ์ด์—์š”.

67๋ฒˆ์งธ ์ค„์— Data Base์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ์ค‘๋ณต๋˜๋Š” ์ฝ”๋“œ๋ฅผ ํ•˜๋‚˜์˜ Method๋กœ ๋งŒ๋“ค์–ด์„œ ๋งค๊ฐœ ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌ๋œ id๊ฐ’์„ ์ „๋‹ฌํ•ด ์ฃผ์—ˆ์–ด์š”.

135๋ฒˆ์งธ ์ค„์„ ๋ณด๊ฒŒ ๋˜๋ฉด JPA Repository์˜ findById()๋ฅผ ํ†ตํ•ด id๊ฐ’์„ ๋„ฃ์–ด ํ•ด๋‹น ๊ฐ’์„ ์ฐพ์„ ์ˆ˜ ์žˆ๋„๋ก ์ฒ˜๋ฆฌํ•œ ๋’ค ์ด๋ฅผ Optional๋กœ ๊ฐ์‹ธ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•ด ์ฃผ์—ˆ์–ด์š”.

76๋ฒˆ์งธ ์ค„์— DataBase์— ์ €์žฅ๋˜์–ด ์žˆ๋˜ ํ‰๋ฌธ ๊ฒŒ์‹œ๊ธ€ ์ œ๋ชฉ๊ฐ’์„ DataEnDecryption ๊ฐ์ฒด์˜ base64Encoder()๋กœ ์ „๋‹ฌํ•˜์—ฌ Base64๊ฐ’์„ ์–ป์–ด๋‚ธ ๋’ค ์ด๋ฅผ cipherKey ๋ณ€์ˆ˜์— ์ €์žฅํ•˜์—ฌ ์ฃผ์—ˆ์–ด์š”.

๊ทธ๋Ÿฐ ๋’ค BoardResponseDTO Builder Pattern์„ ์ด์šฉํ•˜์—ฌ Data Base์—์„œ ์กฐํšŒ๋œ ํ•ด๋‹น ID๊ฐ’์— ๊ฒŒ์‹œ๊ธ€ id์™€ ์ œ๋ชฉ์„ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ–ˆ๊ณ , ์•”ํ˜ธํ™” ๋˜์–ด ์ €์žฅ๋˜์–ด ์žˆ๋˜ ๋‚ด์šฉ์— ๋Œ€ํ•ด ๋ณตํ˜ธํ™” Logic์„ ํƒˆ ์ˆ˜ ์žˆ๋„๋ก ์ฒซ๋ฒˆ์งธ ๋งค๊ฐœ ๋ณ€์ˆ˜์— cipherKey๋ฅผ ์ „๋‹ฌํ•ด ์ฃผ๊ณ , ๋‘๋ฒˆ์งธ ๋งค๊ฐœ๋ณ€์ˆ˜์—๋Š” DataBase์—์„œ ์ฐพ์€ ์•”ํ˜ธํ™”๋œ ๊ฐ’์„ ๋„ฃ์–ด์ฃผ๊ณ , ๋งˆ์ง€๋ง‰์œผ๋กœ ํ•ด๋‹น Logic์ด ๋ณตํ˜ธํ™” Logic์œผ๋กœ ์ฒ˜๋ฆฌ ๋  ์ˆ˜ ์žˆ๋„๋ก 2๋ผ๋Š” ์ •์ˆ˜๊ฐ’์„ ๋„ฃ์–ด ์ฃผ์—ˆ์–ด์š”.

Swagger๋ฅผ ํ†ตํ•œ ๊ฒŒ์‹œ๊ธ€ ์ƒ์„ธ ์กฐํšŒ

 
์ด๋ ‡๊ฒŒ ํ•˜์—ฌ ์œ„์™€ ๊ฐ™์ด ๋ณตํ˜ธํ™”๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์–ด์š”.




DataEnDecryptionTest



์œ„์™€ ๊ฐ™์ด Test Code๋„ ์ž‘์„ฑํ•ด ๋ณด์•˜์–ด์š”.


Test ๊ฒฐ๊ณผ


์ •์ƒ์ ์œผ๋กœ Test๋ฅผ ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ์–ด์š”.





 

 

๐Ÿง ์ฐธ๊ณ  ์ž๋ฃŒ

 

[Java] Cipher, ์ž๋ฐ”์˜ ์•”ํ˜ธํ™”&๋ณตํ˜ธํ™”๋ฅผ ๋‹ด๋‹นํ•˜๋Š” ํด๋ž˜์Šค

์•„๋ž˜ ํ™ˆํŽ˜์ด์ง€์— ์ •๋ฆฌ๋œ ๋‚ด์šฉ์„ ์˜์—ญํ•˜์—ฌ ์ž๋ฐ”์˜ Cipher ํด๋ž˜์Šค์— ๋Œ€ํ•˜์—ฌ ์„ค๋ช…ํ•˜๋Š” ๊ธ€์ž…๋‹ˆ๋‹ค. www.baeldung.com/java-cipher-class ํ•™์Šต ๋ชฉํ‘œ - Cipher๋ž€? - Cipher ๊ฐ์ฒด ์ธ์Šคํ„ด์Šคํ™”ํ•˜๊ธฐ - Keys - Cipher ์ดˆ๊ธฐํ™”(Initial

scshim.tistory.com

 



 

๋ฐฑ๊ฒฌ๋ถˆ์—ฌ์ผํƒ€ ์Šคํ”„๋ง ๋ถ€ํŠธ ์‡ผํ•‘๋ชฐ ํ”„๋กœ์ ํŠธ with JPA:์ด์   ํ”„๋กœ์ ํŠธ๋‹ค!

COUPANG

www.coupang.com

 

 

 

React.js ์Šคํ”„๋ง ๋ถ€ํŠธ AWS๋กœ ๋ฐฐ์šฐ๋Š” ์›น ๊ฐœ๋ฐœ 101:SPA REST API ๊ธฐ๋ฐ˜ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ

COUPANG

www.coupang.com

 

 

 

์Šคํƒ€ํŠธ ์Šคํ”„๋ง ๋ถ€ํŠธ:์ดˆ๊ธ‰ ๊ฐœ๋ฐœ์ž๋“ค์„ ์œ„ํ•œ ๊ฐ€๋ณ๊ณ  ๋„“์€ ์Šคํ”„๋ง ๋ถ€ํŠธ

COUPANG

www.coupang.com

"์ด ํฌ์ŠคํŒ…์€ ์ฟ ํŒก ํŒŒํŠธ๋„ˆ์Šค ํ™œ๋™์˜ ์ผํ™˜์œผ๋กœ, ์ด์— ๋”ฐ๋ฅธ ์ผ์ •์•ก์˜ ์ˆ˜์ˆ˜๋ฃŒ๋ฅผ ์ œ๊ณต๋ฐ›์Šต๋‹ˆ๋‹ค."

 

 

 

 

 

 

 

728x90
๋ฐ˜์‘ํ˜•