DB에 저장된 정보는 회사에 엄청 중요한 자산이야. 근데 이게 해커들한테도 꽤 매력적이지. 그래서 암호화에 대해 고민하는 게 중요해 — 이건 데이터를 남의 눈에서 지키는 방법 중 하나야.
암호화는 비밀 정보를 보호하는 데 도움돼: 예를 들면 비밀번호, 신용카드 번호, 개인정보 같은 거. 그리고 GDPR이나 HIPAA 같은 법적 요구사항도 지킬 수 있어. 만약 데이터 유출이 일어나도, 암호화된 데이터는 훨씬 덜 위험하니까 피해도 줄일 수 있지.
PostgreSQL에는 대칭키 암호화를 위한 편리한 함수들이 있어. pgp_sym_encrypt(data, key)로 원하는 데이터를 암호화하고, pgp_sym_decrypt(encrypted_data, key)로 같은 키를 써서 복호화할 수 있어. 간단하고 안전하지.
데이터 암호화 예시
1단계: 테이블 만들기
users 테이블을 만들고, 암호화된 전화번호를 저장할 컬럼을 추가해보자:
-- 암호화된 데이터를 저장할 컬럼이 있는 테이블 생성
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username TEXT NOT NULL,
phone_encrypted BYTEA -- 여기서 암호화된 전화번호를 저장할 거야
);
2단계: 암호화해서 데이터 넣기
이제 사용자를 추가하면서 전화번호를 암호화해서 넣어보자:
-- 암호화해서 데이터 삽입
INSERT INTO users (username, phone_encrypted)
VALUES ('john_doe', pgp_sym_encrypt('123-456-7890', 'my_secret_key'));
pgp_sym_encrypt 함수 쓰는 거 잘 봐. my_secret_key는 우리가 쓸 대칭키야. 실제로는 이 키를 복잡하게 만들고 잘 보관해야 해.
3단계: 복호화해서 데이터 꺼내기
데이터를 꺼내야 할 때는 이렇게 복호화하면 돼:
-- 복호화해서 데이터 조회
SELECT
username,
pgp_sym_decrypt(phone_encrypted, 'my_secret_key') AS phone
FROM users;
키가 맞으면 원래 전화번호가 보여.
난이도 업: 기존 테이블에 암호화 추가하기
이미 테이블이 있는데, 그 중 한 컬럼만 암호화하고 싶으면 어떻게 할까? 예시로 알아보자.
1단계: 새 컬럼 만들기
예를 들어 customers 테이블이 있고, 신용카드 번호 컬럼을 암호화하고 싶다고 해보자:
-- 암호화된 데이터를 위한 새 컬럼 추가
ALTER TABLE customers ADD COLUMN card_number_encrypted BYTEA;
2단계: 기존 데이터를 암호화해서 새 컬럼에 넣기
기존 데이터를 암호화해서 새 컬럼에 옮겨보자:
-- 데이터 암호화해서 새 컬럼에 저장
UPDATE customers
SET card_number_encrypted = pgp_sym_encrypt(card_number, 'my_other_secret_key');
3단계: 암호화 안 된 컬럼 삭제
데이터 암호화가 끝났으면, 옛날 컬럼은 지워도 돼:
-- 암호화 안 된 옛날 컬럼 삭제
ALTER TABLE customers DROP COLUMN card_number;
이제 데이터는 암호화로 보호되고, 키가 있어야만 접근할 수 있어.
암호화된 데이터 다루기 팁
암호화된 컬럼을 쓸 때 알아둬야 할 중요한 점들이 있어:
데이터 타입:
- 암호화된 값은 바이너리(
BYTEA)로 저장돼. 사람이 읽을 수 있는 형태가 아니야. - 조회할 때는 복호화 함수를 꼭 써야 해.
검색과 필터링:
- 암호화된 데이터로 바로 검색은 안 돼. 예를 들면:
SELECT * FROM users WHERE phone_encrypted = '123-456-7890'; -- 이건 안 돼!
- 대신 복호화해서 조건을 걸어야 해:
SELECT *
FROM users
WHERE pgp_sym_decrypt(phone_encrypted, 'my_secret_key') = '123-456-7890';
성능:
암호화/복호화는 쿼리를 느리게 만들 수 있어. 꼭 필요한 곳에만 쓰는 게 좋아.
실전 예시: 비밀번호 보호
비밀번호 저장은 암호화에서 제일 흔한 작업 중 하나야. 비밀번호를 평문으로 저장하는 건 진짜 위험하니까, 꼭 해싱해서 저장해야 해.
pgcrypto로 비밀번호 해싱하기
crypt() 함수를 써서 비밀번호를 안전하게 해싱해보자:
-- 레코드 삽입할 때 비밀번호 해싱
INSERT INTO users (username, phone_encrypted)
VALUES ('alice', crypt('my_secure_password', gen_salt('bf')));
gen_salt('bf')는 비밀번호 해싱에 쓸 솔트를 만들어줘.
비밀번호를 확인하려면, 해시값을 비교하면 돼:
-- 해싱된 비밀번호 비교
SELECT username
FROM users
WHERE crypt('my_secure_password', phone_encrypted) = phone_encrypted;
보안 꿀팁
- 키는 따로 보관해:
암호화된 데이터랑 대칭키를 같은 DB에 저장하면 안 돼.
- 복잡한 키를 써:
"123" 같은 단순한 키는 너무 쉽게 뚫려.
- 키를 주기적으로 바꿔:
데이터 유출을 막으려면, 가끔씩 키를 바꾸고 데이터도 다시 암호화하는 게 좋아.
GO TO FULL VERSION