사용자 메시지를
암호화된 채로 위험 탐지

OpenAI Embeddings + 동형암호(CKKS)로 서버는 평문을 한 번도 보지 않고
자해·자살·폭력 위험을 실시간 감지합니다.

1,536차원 임베딩
CKKS동형암호 스킴
0서버 평문 노출
3위험 카테고리

AI 서비스의 안전장치가 프라이버시를 침해합니다

🔓

기존 방식

  • 사용자 메시지 → 서버 전송 (평문)
  • 서버가 내용을 직접 읽고 필터링
  • API 로그, 직원 접근, 해킹에 취약
  • 정신건강 등 민감 대화는 노출 불가
🔐

HE Guardrail

  • 메시지는 클라이언트에서 즉시 암호화
  • 서버는 암호문만 연산, 내용 불가
  • 점수만 복호화 — 원문은 복원 불가
  • HIPAA / GDPR 설계 원칙 충족

키워드 필터 대신 의미 벡터를 쓰는 이유

01

우회 불가능한 의미 포착

키워드 필터는 "죽고싶다"는 막지만
"이제 다 끝내려고"는 놓칩니다.
임베딩은 의미를 고차원 벡터로 표현해 표현을 바꿔도 같은 의도를 잡아냅니다.

02

한국어 · 영어 동시 지원

text-embedding-3-small은 다국어를 동일한 벡터 공간에 투영합니다. "죽고 싶다""I want to die"가 같은 리스크 클러스터에 위치합니다.

03

HE와 수학적 호환성

동형암호(CKKS)는 내적(dot product)을 평문 없이 계산합니다. 코사인 유사도 = 정규화 벡터의 내적 → 임베딩이 곧 HE 연산의 입력입니다.

04

캘리브레이션 가능성

레이블된 샘플로 임계값(threshold)과 최소 마진을 F1 최적화 기반으로 자동 튜닝합니다. 키워드 가중치 수동 조정보다 훨씬 체계적입니다.

방법 비교
방법의미 이해다국어HE 호환우회 저항성
키워드 필터
LLM 프롬프트 분류✗ (평문 필요)
Fine-tuned 분류기
OpenAI Embedding + HE

일반 암호화와 동형암호의 차이

일반 암호화 (AES, TLS)

평문
→ 암호화 →
암호문
→ 복호화 필요 →
평문
→ 연산

서버가 연산하려면 반드시 복호화해야 합니다.
복호화 순간 평문이 서버 메모리에 존재합니다.

동형암호 (CKKS)

평문
→ 암호화 →
암호문
→ 암호문 위에서 연산 →
암호화된 결과

서버는 암호문 상태에서 덧셈·내적을 계산합니다.
복호화는 비밀키를 가진 클라이언트만 가능.

CKKS = 부동소수점 근사 동형암호
TenSEAL 라이브러리 구현

단계별 작동 원리

1
CLIENT ZONE

메시지 임베딩 (평문)

사용자 메시지를 OpenAI text-embedding-3-small API로 1,536차원 실수 벡터로 변환합니다. 이 단계까지는 평문입니다.

// 평문 단계: 클라이언트 디바이스에서만 실행
vec = openai.embed("죽고 싶어서 힘들어")
// → [0.021, -0.103, 0.847, ...] (1536차원)
2
CLIENT ZONE

CKKS 동형암호 암호화

공개 컨텍스트(public context)로 벡터를 암호화합니다. 이 시점부터 원문 복원은 비밀키 없이 불가능합니다.

// 암호화: 공개키만 필요, 비밀키 불필요
enc_vec = ts.ckks_vector(pub_ctx, vec)
payload = base64(enc_vec.serialize())
// → 서버로 전송되는 것: 암호문 blob
3
SERVER ZONE (평문 불가)

암호문 위에서 코사인 유사도 계산

서버는 평문 위험 프로파일 벡터(공개)와 암호화된 사용자 벡터의 내적을 계산합니다. 내적 결과도 암호화 상태입니다.

// 서버: 평문을 절대 보지 않음
// risk_vec = 공개된 위험 프로파일 중심 벡터
enc_score = enc_vec.dot(risk_vec)
// enc_score는 여전히 암호문 — 서버 접근 불가
4
SECURE ZONE (비밀키 보유)

점수만 복호화 → 경보 판정

비밀 컨텍스트(secret key)로 스칼라 점수만 복호화합니다. 원본 메시지는 복원 불가능하며 오직 "위험도 점수"만 얻습니다.

// 복호화: 비밀키 보안 영역에서만
score = enc_score.decrypt()[0]  # → 0.73
alert = score >= threshold      # → ALERT
// 원문 "죽고 싶어서..." 는 절대 복원되지 않음

정확히 무엇이 암호화되고 무엇이 평문인가

👤 사용자 / 클라이언트
📝
평문 메시지
"죽고 싶어"
PLAINTEXT
↓ OpenAI API 호출
🔢
임베딩 벡터
[0.021, -0.103, ...] 1536차원
PLAINTEXT
↓ CKKS 암호화
🔐
암호화된 벡터
base64 blob (~60KB)
CIPHERTEXT
→ HTTPS 전송 →
서버로 전송되는 것:
암호문 blob만
⚙️ 서버 (평문 접근 불가)
📊
위험 프로파일 벡터
3개 카테고리 중심점 (공개)
PUBLIC
↓ dot product (HE)
🔐
암호화된 유사도 점수
3개 카테고리 × 암호문
CIPHERTEXT
→ 전달 →
점수 복호화:
보안 영역에서만
🔑 보안 영역 (비밀키)
🔑
비밀 컨텍스트
secret_context.tenseal
SECRET KEY
↓ 복호화
⚠️
스칼라 점수만
score=0.73 → ALERT
SCORE ONLY

요약: 무엇이 평문이고 무엇이 암호화되나?

평문 (Plaintext)
  • 사용자 메시지 — 클라이언트 디바이스 내부
  • 임베딩 벡터 — 클라이언트에서 암호화 전
  • 위험 프로파일 중심 벡터 — 공개 DB
  • 최종 스칼라 점수 — 보안 영역에서만 복호화
암호문 (Ciphertext)
  • 사용자 임베딩 벡터 — 서버 전송 시
  • 중간 연산 결과 (내적)
  • 카테고리별 유사도 점수 — 보안 영역 전달 전
절대 노출 안됨
  • 원본 메시지 텍스트 — 서버에 도달 불가
  • 임베딩 벡터 — 서버는 암호문만 봄
  • 비밀키 — 클라이언트/보안 영역에만 존재

상용화 시 키 관리 아키텍처

개발/PoC

로컬 파일 방식

공개 컨텍스트artifacts/public_context.tenseal누구나 소유 가능, 암호화 전용
비밀 컨텍스트secure/secret_context.tenseal보안 영역 로컬 파일, .gitignore 필수
프로덕션

관리형 KMS 방식

공개 컨텍스트CDN 배포, 클라이언트 다운로드
비밀키AWS KMS / GCP Cloud KMS / HSM에 저장
절대 메모리 외부 미노출, 감사 로그 필수
키 로테이션90일 주기 교체, 구 암호문 재암호화 파이프라인
멀티 테넌트조직별 독립 키 쌍 → 테넌트 간 격리
왜 공개 컨텍스트(갈루아 키)가 필요한가?
CKKS에서 벡터 회전(rotation)과 내적 연산은 갈루아 키(Galois key)가 필요합니다. 이는 공개키의 일부로 배포하며, 비밀키 없이는 복호화에 사용할 수 없습니다.

다른 임베딩 대비 OpenAI를 선택한 이유

🌐

다국어 통합 벡터 공간

text-embedding-3-small은 100개 이상 언어를 동일한 고차원 공간에 투영합니다. 한국어 "죽고 싶다"와 영어 "I want to die"가 인접한 벡터를 가집니다.

📐

정규화된 1536차원

CKKS 내적 연산에 최적화된 차원수. L2 정규화 후 내적 = 코사인 유사도. 추가 변환 없이 HE 파이프라인에 직접 연결됩니다.

🚀

API 일관성 · 버전 관리

모델 버전을 고정하면 임베딩 공간이 변하지 않습니다. 위험 프로파일 DB와 사용자 임베딩이 항상 같은 공간을 공유하는 것이 보장됩니다.

💡

LLM과의 역할 분리

임베딩은 의미 측정, LLM은 경보 설명 생성에만 사용합니다. 임베딩은 평문 노출 없이 HE 파이프라인 진입, LLM은 복호화된 구조화 데이터만 처리합니다.

임베딩 vs LLM 분류 — 왜 임베딩이 HE에 필수인가
LLM 프롬프트 분류
텍스트 → API → 분류 결과 (평문 전송 필수)
Embedding + HE
텍스트 → 임베딩
암호화 → 서버 연산 → 복호화 (내용 미노출)

실제 동형암호 파이프라인을 직접 체험해보세요

1메시지 입력
2OpenAI 임베딩
3CKKS 암호화
4HE 내적 · 판정

실제 TenSEAL CKKS 백엔드와 연결된 라이브 데모입니다.
서버는 암호문만 연산하며 원문 메시지를 절대 볼 수 없습니다.

라이브 데모 열기 →

기술 스택

OpenAI API
text-embedding-3-small
gpt-4.1-mini (경보 설명)
TenSEAL
CKKS 동형암호
Python 라이브러리
FastAPI
백엔드 HE 연산 서버
Cloud Run 배포
Next.js
프론트엔드 웹 앱
실시간 파이프라인 시각화
Google Cloud Run
서버리스 백엔드
자동 스케일링
CKKS 스킴
poly_modulus=8192
scale_bits=40