코드 생성 로직에 암호화가 필요했던 이유
서비스에서 식별 코드를 생성할 때, 기존에는 단순히 데이터베이스의 PK(id) 값을 이용해 코드를 만들었다.
(id가 123이면 PRE0123과 같은 코드가 생성되는 방식)
하지만 이 방식에는 치명적인 단점이 있었는데, id 값이 그대로 외부에 노출된다는 점이다.
이로 인해 전체 등록 수 추정, 연속된 id 추적 등 보안상 문제가 발생할 수 있어 코드에 암호화를 적용하였다.
1. 첫 번째 시도: XOR 연산을 이용한 암호화
처음에는 id 값에 비밀키(SECRET_NUMBER)를 XOR 연산하여 외부에서 id를 직접적으로 알 수 없게 하는 방식을 도입했다.
const encoded = (id ^ SECRET_NUMBER).toString(36).toUpperCase().padStart(6, '0');이 방식은 어느 정도 id 노출을 막을 수 있었지만 연속된 id(예: 145, 146 등)는 여전히 비슷한 패턴의 코드가 생성되어 완벽한 암호화라고 보기 어려웠다.
2. 두 번째 시도: 해시(hash) 기반 코드 생성
더 강력한 보안을 위해 Node.js의 crypto 라이브러리의 SHA-256 해시를 활용했다.
- id 값을 해시로 변환하고
- 해시값의 앞 8자리를 코드로 사용
- 예시:
PRE99160B2
이 방식은
- id와 코드의 직접적 연관성이 사라지고
- 중복 가능성도 극히 낮아져 실질적으로 안전한 코드 생성이 가능해졌다.
3. 세 번째 시도: salt 적용으로 보안 강화
여기서 한 단계 더 나아가, salt(비밀 문자열)를 추가로 해시 입력값에 포함시켰다.
const hash = crypto
.createHash('sha256')
.update(`${kind}-${id}-${SALT}`)
.digest('hex')
.toUpperCase();
const codeBody = hash.slice(0, 8);
return kindToPrefix[kind] + codeBody;- salt가 바뀌면 같은 id여도 완전히 다른 코드가 생성되고, salt는 환경변수 등 안전한 곳에 보관해 외부 노출을 방지했다.