1๏ธโฃ ๋์นญํค(AES)๋ง ์ฌ์ฉํ ๊ฒฝ์ฐ:
2๏ธโฃ ๋น๋์นญํค(RSA)๋ง ์ฌ์ฉํ ๊ฒฝ์ฐ:
3๏ธโฃ ๊ทธ๋ ๋ค๋ฉด?
โ ๋ ๋ฐฉ์์ ์ฅ์ ๋ง ํฉ์น์! = ํ์ด๋ธ๋ฆฌ๋ ์ํธํ
= ๋์นญํค๋ก ๋ฐ์ดํฐ ์ํธํ + ๋น๋์นญํค๋ก ๋์นญํค ์ํธํ
๐ ํฐ ๋ณด๋ฌผ์์(๋ฏผ๊ฐํ ๋ฐ์ดํฐ) โ ๐ฆ ํ๋ฐฐ์์(AES)๋ก ํฌ์ฅ (๋น ๋ฆ!)
๐ ํ๋ฐฐ์์ ์ด์ (AESํค) โ ๐ ํน์๊ธ๊ณ (RSA)๋ก ํฌ์ฅ (์์ !)
๊ฒฐ๊ณผ: ๋น ๋ฅด๋ฉด์๋ ์์ ํ ์ ๋ฌ! โจ
"randomKey123")"๊ฐ์ธ์ ๋ณด๋ฐ์ดํฐ" + "randomKey123" โ "encrypted_data_xyz""randomKey123" + RSA๊ณต๊ฐํค โ "encrypted_key_abc""encrypted_data_xyz" (AES๋ก ์ํธํ๋ ๋ฐ์ดํฐ)"encrypted_key_abc" (RSA๋ก ์ํธํ๋ AESํค)RSA๊ฐ์ธํค + "encrypted_key_abc" โ "randomKey123""randomKey123" + "encrypted_data_xyz" โ "๊ฐ์ธ์ ๋ณด๋ฐ์ดํฐ"// 1๋จ๊ณ: ์๋ฒ์ ์ํธํ ํค ์์ฒญ
const response = await fetch('/api/crypto/generate-keys', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: currentUser.id,
purpose: 'data-encryption'
})
});
const { publicKey } = await response.json();
// 2๋จ๊ณ: ํด๋ผ์ด์ธํธ์์ ํ์ด๋ธ๋ฆฌ๋ ์ํธํ
// AES ํค ์์ฑ (๋งค๋ฒ ์๋ก์ด ๋๋ค ํค!)
const aesKey = await crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 256 },
true, ['encrypt', 'decrypt']
);
// ๋ฏผ๊ฐํ ๋ฐ์ดํฐ AES ์ํธํ
const iv = crypto.getRandomValues(new Uint8Array(12));
const encryptedData = await crypto.subtle.encrypt(
{ name: 'AES-GCM', iv: iv },
aesKey,
new TextEncoder().encode(sensitiveData)
);
// AES ํค๋ฅผ RSA ๊ณต๊ฐํค๋ก ์ํธํ
const rsaKey = await importRsaPublicKey(publicKey);
const encryptedAesKey = await crypto.subtle.encrypt(
{ name: 'RSA-OAEP' },
rsaKey,
await crypto.subtle.exportKey('raw', aesKey)
);
// 3๋จ๊ณ: ์ํธํ๋ ๋ฐ์ดํฐ ์ ์ก
await fetch('/api/secure-data/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
encryptedData: arrayBufferToBase64(encryptedData),
encryptedKey: arrayBufferToBase64(encryptedAesKey),
iv: arrayBufferToBase64(iv)
})
});
| ์ฉ์ด | ์ฌ์ด ์ค๋ช | ์ญํ |
|---|---|---|
| ๋์นญํค (AES) | ๊ฐ์ ์ด์ ๋ก ์ ๊ทธ๊ณ ์ด๊ธฐ | ๋น ๋ฅธ ๋ฐ์ดํฐ ์ํธํ |
| ๋น๋์นญํค (RSA) | ๋ค๋ฅธ ์ด์ ๋ก ์ ๊ทธ๊ณ ์ด๊ธฐ | ์์ ํ ํค ์ ๋ฌ |
| ๊ณต๊ฐํค | ๋ชจ๋ ์ฌ๋์ด ์์๋ ๋๋ ํค | ๋ฐ์ดํฐ ์ํธํ์ฉ |
| ๊ฐ์ธํค | ์ ๋ ๋น๋ฐ์ธ ํค | ๋ฐ์ดํฐ ๋ณตํธํ์ฉ |
| ํ์ด๋ธ๋ฆฌ๋ | ๋ ๋ฐฉ์ ์กฐํฉ | ๋น ๋ฆ + ์์ ํจ |
| IV | ์ํธํ ๋ณด์กฐ ์ ๋ณด | ๊ฐ์ ๋ฐ์ดํฐ๋ ๋ค๋ฅด๊ฒ ์ํธํ |
๋ณด์ != ๋ณต์กํจ: ๋ณต์กํ ๊ฒ ํญ์ ์ข์ ๊ฑด ์๋์ผ. ์ ์ฌ์ ์์ ๋ง๋ ๋ฐฉ์ ์ ํ์ด ์ค์!
ํค๋ ๋งค๋ฒ ์๋ก ๋ง๋ ๋ค:
ํ๋ก ํธ vs ๋ฐฑ์๋ ์ญํ ๋ถ๋ด:
ํ๋ฐฐ ๋น์ ๊ฐ ์ฐฐ๋ก: ํฐ ๋ฌผ๊ฑด(๋ฐ์ดํฐ)์ ์ผ๋ฐํ๋ฐฐ(AES), ์์ ์ด์ (ํค)๋ง ํน์๋ฐฐ์ก(RSA)
crypto.subtle API ์์ธ ์ฌ์ฉ๋ฒ// ArrayBuffer๋ฅผ Base64๋ก ๋ณํ
function arrayBufferToBase64(buffer) {
const bytes = new Uint8Array(buffer);
return btoa(String.fromCharCode(...bytes));
}
// RSA ๊ณต๊ฐํค Import
async function importRsaPublicKey(pemKey) {
const keyData = pemToArrayBuffer(pemKey);
return await crypto.subtle.importKey(
'spki', keyData,
{ name: 'RSA-OAEP', hash: 'SHA-256' },
false, ['encrypt']
);
}
"ํฐ ๋ฐ์ดํฐ๋ ๋น ๋ฅธ AES๋ก, ์์ ํค๋ ์์ ํ RSA๋ก!" - ์ด๊ฒ ํ์ด๋ธ๋ฆฌ๋ ์ํธํ์ ํต์ฌ! ๐โจ