| ํญ๋ชฉ | ๊ฐ |
|---|---|
| ์ํธํ ์๊ณ ๋ฆฌ์ฆ | AES-256-GCM |
| ํค ๊ธธ์ด | 256๋นํธ (32๋ฐ์ดํธ) |
| IV ๊ธธ์ด | 12๋ฐ์ดํธ |
| ์ธ์ฆ ํ๊ทธ(AuthTag) | 16๋ฐ์ดํธ (128-bit) |
| ์ถ๋ ฅ ํฌ๋งท | Base64(IV + ์ํธ๋ฌธ + AuthTag) |
| ๋ณตํธํ ๊ฐ๋ฅ ์กฐ๊ฑด | ๋น๋ฐํค + IV + ์ํธ๋ฌธ + AuthTag |
AES-GCM์ ํ์กด ์ต๊ณ ์์ค์ ์์ ์ฑ์ ์ ๊ณตํ๋ ๋ฐฉ์์ผ๋ก,
finger-basic์ ์ํธํ ๊ตฌํ์ ๊ตญ์ ํ์ค์ ์์ ํ ๋ถํฉํฉ๋๋ค.
์ํธํ(Encrypt)
โ
์
๋ ฅ โ IV ์์ฑ โ AES-GCM ์ํธํ โ AuthTag ์์ฑ
โ
[IV + ์ํธ๋ฌธ + AuthTag] ๊ฒฐํฉ
โ
Base64 ๋ฌธ์์ด๋ก ๋ณํํ์ฌ DB ์ ์ฅ
๋ณตํธํ(Decrypt)
โ
Base64 โ ๋ฐ์ดํธ ๋ฐฐ์ด ๋ณต์
โ
์ 12๋ฐ์ดํธ = IV ์ถ์ถ
๋๋จธ์ง = ์ํธ๋ฌธ + AuthTag
โ
AES-GCM ๋ณตํธํ โ ์๋ ๋ฌธ์์ด ๋ฐํ
์๋๋ encrypt() ๋ก์ง์ ํ๋ฆ๋๋ก โ๊ฐ๋ฐ์ ๋๋์ดโ์์ ์ค๋ช
ํ ๊ฒ.
if (plainText == null || plainText.isEmpty()) {
return plainText;
}
๋ฏธ๋ฆฌ ๋ฐฉ์ด ์ฝ๋(Null Safe)
byte[] iv = new byte[GCM_IV_LENGTH];
SECURE_RANDOM.nextBytes(iv);
IV = Initial Vector = ์ํธํ "์์์ "
๐ฒ ๋งค๋ฒ ๋ค๋ฅธ ์คํํธ ์ง์ ์์ ์ํธํ๋ฅผ ์์ํ๋ ์ฃผ์ฌ์
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_LENGTH, iv);
๐ฆ ํ๋ฐฐ ๋ด์ธ ์คํฐ์ปค ๊ธฐ๋ฅ์ด AuthTag
SecretKeySpec keySpec =
new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), KEY_ALGORITHM);
๐ ์ง์ง ์๋ฌผ์ ์ด์
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, spec);
byte[] encrypted = cipher.doFinal(plainText.getBytes(UTF_8));
๊ฒฐ๊ณผ = ์ํธ๋ฌธ + AuthTag
AES-GCM์ ๋ด๋ถ์ ์ผ๋ก AuthTag(16๋ฐ์ดํธ)๋ฅผ ์ํธ๋ฌธ ๋ค์ ๋ถ์ฌ์ ๋ฐํํจ.
byte[] combined = new byte[12 + encrypted.length];
System.arraycopy(iv, 0, combined, 0, 12);
System.arraycopy(encrypted, 0, combined, 12, encrypted.length);
์ต์ข ๊ตฌ์กฐ:
[IV][CipherText + AuthTag]
return Base64.getEncoder().encodeToString(combined);
์
๋ ฅ โ ๋๋ค IV ์์ฑ
โ
AES-256-GCM ์ํธํ (AuthTag ํฌํจ)
โ
[IV + ์ํธ๋ฌธ + AuthTag] ๊ฒฐํฉ
โ
Base64 ์ธ์ฝ๋ฉ โ ์ ์ฅ
์ํธํ ๊ณผ์ ์ด ์ดํด๋๋ฉด ๋ณตํธํ๋ ๋งค์ฐ ์ง๊ด์ ์.
byte[] decoded = Base64.getDecoder().decode(cipherText);
byte[] iv = Arrays.copyOfRange(decoded, 0, 12);
byte[] encrypted = Arrays.copyOfRange(decoded, 12, decoded.length);
AES-GCM์ CipherText ๋ค์ ์๋์ผ๋ก AuthTag(16๋ฐ์ดํธ)๋ฅผ ํฌํจํจ.
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);
byte[] decrypted = cipher.doFinal(encrypted);
Base64 ๋์ฝ๋
โ
[IV 12๋ฐ์ดํธ][์ํธ๋ฌธ+AuthTag] ๋ถ๋ฆฌ
โ
AES-GCM ๋ณตํธํ (IV + Key)
โ
์๋ณธ ํ
์คํธ ๋ฐํ
AES ๋ณด์์ ํต์ฌ์ "๋น๋ฐํค"์ด์ง IV๊ฐ ์๋๋ค.
| ์์ | ์ญํ | ๊ณต๊ฐ ์ฌ๋ถ |
|---|---|---|
| ๋น๋ฐํค | ๋ณตํธํ ๊ฐ๋ฅ ์ฌ๋ถ ๊ฒฐ์ | โ ๋น๊ณต๊ฐ |
| IV | ์ํธํ ๋ฌด์์์ฑ ์ ๊ณต | โ ๊ณต๊ฐ ๊ฐ๋ฅ |
| AuthTag | ๋ณ์กฐ ๊ฐ์ง | ๊ณต๊ฐ ๊ฐ๋ฅ |
์ฆ:
์ํธํ("010-1234-5678") โ ํญ์ ๊ฐ์ ์ํธ๋ฌธ
์ฆ ํด์ปค๋:
์:
์ํธํ("010-1234-5678") โ abc123
์ํธ๋ฌธ์ด abc123์ด๋ฉด โ ์ด ๊ฐ์ด๊ตฌ๋!
์ํธํ("010-1234-5678") โ abc123
์ํธํ("010-1234-5678") โ lp0aaK
์ํธํ("010-1234-5678") โ Qj2mLx
๋์ผํ ๋ฐ์ดํฐ๊ฐ ์์ ํ ๋ค๋ฅธ ์ํธ๋ฌธ โ ํจํด ๋ถ์ ๋ถ๊ฐ๋ฅ
์ด๊ฒ ๋ฐ๋ก ๋ณด์.
| ์ฅ์ | ์ค๋ช |
|---|---|
| ๋ณ์กฐ ๋ฐฉ์ง | AuthTag ์๋ ๊ฒ์ฆ |
| Padding Attack ๋ฉด์ญ | CBC ์ทจ์ฝ์ ์ ๊ฑฐ |
| ๊ณ ์ | ์คํธ๋ฆฌ๋ฐ ์ฒ๋ฆฌ ์ฑ๋ฅ ์ฐ์ |
| TLS 1.3 ๊ธฐ๋ฐ | HTTPS๊ฐ ๋ด๋ถ์ ์ผ๋ก ์ฐ๋ ๋ชจ๋ |
์ฆ, ํ๋ ์ํธํ์ ํ์ค
ํ์ฌ ์ค์๋น์ค์์ ๊ฐ์ฅ ๊ถ์ฅ๋๋ ์ํธํ ๋ฐฉ์