암호화 기초 - 대칭키 vs 비대칭키, 개발자가 알아야 할 것
AES, RSA, HTTPS가 어떻게 작동하는지 모른다면 이 글을 읽으세요. 암호화의 핵심 개념을 실전 예제로 설명합니다.
Toolypet Team
Development Team
암호화 기초: 대칭키 vs 비대칭키
"이 데이터 암호화해서 보내주세요."
이 말을 들었을 때, 무엇을 어떻게 해야 하는지 정확히 아시나요?
암호화에는 크게 두 가지 방식이 있습니다. 각각 언제 사용하는지 모르면, 보안 설계가 잘못될 수 있습니다.
암호화 vs 해싱
먼저 혼동하기 쉬운 개념을 정리합니다.
| 암호화 | 해싱 | |
|---|---|---|
| 방향 | 양방향 (복호화 가능) | 단방향 (복호화 불가) |
| 목적 | 데이터 보호 | 무결성 확인, 비밀번호 저장 |
| 키 필요 | ✅ | ❌ |
| 예시 | AES, RSA | SHA-256, bcrypt |
암호화: 원본을 되찾을 수 있음 해싱: 원본을 되찾을 수 없음
비밀번호 저장에는 해싱, 데이터 전송에는 암호화를 사용합니다.
대칭키 암호화
개념
하나의 키로 암호화하고, 같은 키로 복호화합니다.
원본 + 키 → 암호화 → 암호문
암호문 + 키 → 복호화 → 원본
예시: 자물쇠
집 열쇠를 생각하세요. 같은 열쇠로 잠그고, 같은 열쇠로 엽니다.
대표 알고리즘
| 알고리즘 | 키 길이 | 상태 |
|---|---|---|
| AES-256 | 256bit | ✅ 현재 표준 |
| AES-128 | 128bit | ✅ 안전 |
| 3DES | 168bit | ⚠️ 레거시 |
| DES | 56bit | ❌ 취약 |
코드 예시 (Node.js)
const crypto = require('crypto');
// 키 생성 (실제로는 안전하게 저장해야 함)
const key = crypto.randomBytes(32); // AES-256
const iv = crypto.randomBytes(16); // 초기화 벡터
// 암호화
function encrypt(text) {
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');
return encrypted;
}
// 복호화
function decrypt(encrypted) {
const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');
return decrypted;
}
const secret = "민감한 데이터";
const encrypted = encrypt(secret);
const decrypted = decrypt(encrypted);
console.log(encrypted); // "a3f8b2c1..."
console.log(decrypted); // "민감한 데이터"
장단점
| 장점 | 단점 |
|---|---|
| 빠름 | 키 공유 문제 |
| 대용량 데이터에 적합 | 키가 노출되면 끝 |
| 구현 간단 | 키 관리 복잡 |
키 공유 문제
A가 B에게 암호화된 메시지를 보내려면, B에게 키를 먼저 전달해야 합니다.
그런데 그 키를 어떻게 안전하게 전달하죠?
이 문제를 해결하는 것이 비대칭키 암호화입니다.
비대칭키 암호화
개념
두 개의 키를 사용합니다:
- 공개키 (Public Key): 누구나 알아도 됨
- 개인키 (Private Key): 절대 공개하면 안 됨
공개키로 암호화 → 개인키로만 복호화
개인키로 서명 → 공개키로 검증
예시: 우체통
- 공개키 = 우체통 (누구나 편지를 넣을 수 있음)
- 개인키 = 우체통 열쇠 (주인만 편지를 꺼낼 수 있음)
대표 알고리즘
| 알고리즘 | 용도 | 키 길이 |
|---|---|---|
| RSA | 암호화, 서명 | 2048+ bit |
| ECDSA | 서명 | 256+ bit |
| Ed25519 | 서명 | 256bit |
코드 예시 (Node.js RSA)
const crypto = require('crypto');
// 키 쌍 생성
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
modulusLength: 2048,
});
// 공개키로 암호화
function encryptWithPublic(text) {
return crypto.publicEncrypt(publicKey, Buffer.from(text)).toString('base64');
}
// 개인키로 복호화
function decryptWithPrivate(encrypted) {
return crypto.privateDecrypt(privateKey, Buffer.from(encrypted, 'base64')).toString();
}
const secret = "민감한 데이터";
const encrypted = encryptWithPublic(secret);
const decrypted = decryptWithPrivate(encrypted);
console.log(decrypted); // "민감한 데이터"
디지털 서명
개인키로 서명하면, 공개키로 누가 서명했는지 확인할 수 있습니다.
// 개인키로 서명
const sign = crypto.createSign('SHA256');
sign.update('메시지');
const signature = sign.sign(privateKey, 'base64');
// 공개키로 검증
const verify = crypto.createVerify('SHA256');
verify.update('메시지');
const isValid = verify.verify(publicKey, signature, 'base64');
console.log(isValid); // true
장단점
| 장점 | 단점 |
|---|---|
| 키 공유 문제 해결 | 느림 (대칭키 대비 1000배) |
| 디지털 서명 가능 | 대용량 데이터에 부적합 |
| 공개키 자유롭게 배포 | 키 길이가 김 |
실전: 둘을 함께 사용 (하이브리드 암호화)
HTTPS가 작동하는 방식입니다.
과정
1. 서버: RSA 공개키/개인키 생성
2. 클라이언트: 서버의 공개키 받음
3. 클라이언트: AES 세션키 생성
4. 클라이언트: 세션키를 RSA 공개키로 암호화 → 서버 전송
5. 서버: RSA 개인키로 세션키 복호화
6. 양쪽: AES 세션키로 데이터 암호화 통신
왜 이렇게 하는가
- RSA: 키 교환에만 사용 (느리지만 안전)
- AES: 실제 데이터 암호화 (빠름)
각자의 장점만 사용합니다.
실무 체크리스트
대칭키 (AES) 사용 시
- AES-256 또는 AES-128 사용
- 매 암호화마다 새 IV(초기화 벡터) 생성
- 키는 환경변수 또는 KMS에 저장
- ECB 모드 사용 금지 (CBC, GCM 사용)
비대칭키 (RSA) 사용 시
- 최소 2048bit 키 사용
- 개인키 절대 노출 금지
- OAEP 패딩 사용 (PKCS#1 v1.5 피하기)
- 키 로테이션 정책 수립
FAQ
Q: API 키를 암호화해서 저장해야 하나요?
A: 암호화보다는 환경변수나 시크릿 관리 도구(AWS Secrets Manager, HashiCorp Vault)를 사용하세요. 암호화해도 복호화 키 관리 문제가 남습니다.
Q: 클라이언트에서 암호화하면 안전한가요?
A: 아니요. 클라이언트 코드는 누구나 볼 수 있어 키가 노출됩니다. 민감한 암호화는 서버에서 해야 합니다.
Q: SHA-256도 암호화인가요?
A: 아니요. SHA-256은 해싱입니다. 복호화가 불가능합니다. 데이터를 되찾아야 한다면 AES 같은 암호화를 사용하세요.
요약
| 상황 | 사용 알고리즘 |
|---|---|
| 대용량 데이터 암호화 | AES-256 |
| 키 교환 | RSA, ECDH |
| 디지털 서명 | RSA, ECDSA, Ed25519 |
| 비밀번호 저장 | bcrypt, Argon2 (해싱) |
| HTTPS 통신 | 하이브리드 (RSA + AES) |
관련 도구
저자 소개
Toolypet Team
Development Team
The Toolypet Team creates free, privacy-focused web tools for developers and designers. All tools run entirely in your browser with no data sent to servers.