Tan Kim

encryption

암호화 (Encryption)

대칭키 vs 비대칭키

항목 대칭키 비대칭키
키 종류 암호화 = 복호화 (같은 키) 공개키 + 개인키
속도 빠름 느림
키 배포 안전한 공유 필요 공개키는 공유 가능
알고리즘 AES, DES RSA, ECC
사용 대용량 데이터 암호화 키 교환, 전자서명

해시 함수

단방향 변환. 복호화 불가.

알고리즘 출력 길이 사용 여부
MD5 128bit 보안 용도 사용 금지
SHA-1 160bit 보안 용도 사용 금지
SHA-256 256bit 현재 표준
SHA-512 512bit 현재 표준
bcrypt 가변 패스워드 해싱
argon2 가변 패스워드 해싱 (권장)

AES (Advanced Encryption Standard)

현재 표준 대칭키 암호. 128/192/256비트 키.

import crypto from 'crypto'
 
const ALGORITHM = 'aes-256-gcm'
const KEY = crypto.randomBytes(32)  // 256비트
 
function encrypt(text: string) {
  const iv = crypto.randomBytes(12)
  const cipher = crypto.createCipheriv(ALGORITHM, KEY, iv)
  const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()])
  const tag = cipher.getAuthTag()
  return { encrypted: encrypted.toString('hex'), iv: iv.toString('hex'), tag: tag.toString('hex') }
}
 
function decrypt(encrypted: string, iv: string, tag: string) {
  const decipher = crypto.createDecipheriv(ALGORITHM, KEY, Buffer.from(iv, 'hex'))
  decipher.setAuthTag(Buffer.from(tag, 'hex'))
  return decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8')
}

RSA

비대칭키 암호. 키 교환, 전자서명에 사용.

const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
})
 
// 공개키로 암호화
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from('secret'))
 
// 개인키로 복호화
const decrypted = crypto.privateDecrypt(privateKey, encrypted)
 
// 개인키로 서명
const sign = crypto.createSign('SHA256')
sign.update('message')
const signature = sign.sign(privateKey, 'hex')
 
// 공개키로 검증
const verify = crypto.createVerify('SHA256')
verify.update('message')
verify.verify(publicKey, signature, 'hex')  // true/false

민감 정보 마스킹

function maskCard(number: string) {
  return number.replace(/(\d{4})\d{8}(\d{4})/, '$1********$2')
}
// "1234123412341234" → "1234********1234"
 
function maskEmail(email: string) {
  const [local, domain] = email.split('@')
  return local[0] + '***@' + domain
}
// "김탄@example.com" → "김***@example.com"

메모