해시와 암호화
데이터를 안전하게 보호하기 위한 핵심 기술.
해시 (Hash)
임의의 길이의 데이터를 고정한 길이의 고유한 값(해시 값 또는 다이제스트)으로 변환하는 과정.
특징
- 단방향성(One-way): 해시 값에서 원본 데이터로 복원하는 것이 불가능하다. (복호화 불가능)
- 고정된 출력 길이: 입력 데이터의 길이에 상관없이 항상 일정한 길이의 해시 값을 출력한다.
- 충돌 회피성(Collision Resistence): 서로 다른 입력이 같은 해시 값을 생성할 확률이 매우 낮아야 한다.
사용 예시
- 비밀번호 저장: 원본 비밀번호를 DB에 저장하지 않고 해시 값만 저장한다. 로그인 시 입력된 비밀번호를 해시하여 저장된 해시 값과 비교한다.
- 데이터 무결성 확인: 파일이 전송 중 변조되지 않았는지 확인하기 위해 파일의 해시 값을 비교한다.
SHA (Secure Hash Algorithm) 원리
- 미국 NSA가 설계한 암호학적 해시 함수의 계열.
- 현재 주로 사용되는 것은 SHA-2 (ex. SHA-256, SHA-512)와 SHA-3이다.
- 입력 메시지를 일정한 블록 단위로 나누어 복잡한 수학적 변환(압축 함수)을 반복적으로 적용하여 최종 해시 값을 생성한다. 해시의 대표적인 알고리즘으로 높은 보안성과 충돌 회피성을 제공하여 비밀번호 저장 등에 널리 사용된다.
암호화 (Encryption)
키(key)를 사용하여 원본 데이터(평문)를 알아보지 못하는 형태(암호문)로 변환하고, 다시 복호화(Decryption)하여 평문으로 되돌릴 수 있는 과정.
AES (Advanced Encryption Standard) - 대칭키 암호화
원리
암호화와 복호화에 동일한 키(대칭키)를 사용하는 방식이다.

특징
- 속도가 빠르다. 대용량 데이터 암호화에 효율적이다.
- 키 관리: 암호화된 데이터를 주고받는 사람들끼리 비밀 키를 안전하게 공유하고 관리하는 것이 중요하다.
사용 예시
DB에 저장되는 전화번호나 민감 정보 등, 복호화가 필요한 경우에 주로 사용된다.
RSA (Rivest-Shamir-Adleman) - 비대칭키 (공개키) 암호화
원리
한 쌍의 키, 공개키(Public Key)와 개인키(Private Key)를 사용한다.
- 공개키: 누구나 알 수 있으며 주로 암호화에 사용된다.
- 개인키: 소유자만 가지며, 주로 복호화에 사용된다.
특징
- 보안성: 키 분배가 용이하고 안전하다.
- 속도: 대칭키 방식보다 느리다.
사용 예시
SSL/TLS 통신(웹 통신 보안), 디지털 서명 등에 사용되어 키를 안전하게 교환하거나 신원을 인증하는 데 활용된다.
요약
| 구분 | 해시 | AES(대칭키) | RSA(비대칭키) |
|---|
| 키 필요? | ❌ 없음 | ✔ 동일한 키 | ✔ 공개키·개인키 |
| 복호화 가능? | ❌ 불가 | ✔ 가능 | ✔ 가능 |
| 속도 | 매우 빠름 | 빠름 | 느림 |
| 용도 | 비번 저장, 무결성 | 데이터 암호화 | 키 교환, 서명 |
인증 및 인가
사용자가 누구인지 확인하고 (인증), 그 사용자에게 어떤 작업을 허용할지 결정하는 (인가) 과정은 시스템 보안의 근간이다.
- 인증 (Authentication): 당신이 누구인지 확인하는 과정. (ex. 로그인 시 ID/PW 확인)
- 인가 (Authorization): 인증된 사용자에게 특정 리소스에 접근할 권한이 있는지 확인하는 과정. (ex. 일반 사용자는 관리자 페이지 접근 불가)
세션 (Session)과 쿠키 (Cookie)
HTTP는 기본적으로 무상태 (Stateless) 프로토콜이라 매 요청마다 클라이언트를 식별할 수 없다. 이를 보완하기 위해 세션과 쿠키를 사용한다.
| 구분 | 쿠키 (Cookie) | 세션 (Session) |
|---|
| 저장 위치 | 클라이언트 (브라우저) | 서버 (메모리, DB 등) |
| 작동 방식 | 서버가 Session ID가 포함된 쿠키를 발행 → 클라이언트가 매 요청마다 쿠키를 포함하여 전송 | |
| 보안성 | 비교적 취약 (클라이언트 변조 및 탈취 위험) | 비교적 우수 (중요 정보는 서버에 저장) |
| 확장성 | 서버 부하 적음 | 서버 부하 발생 (세션 저장소 필요) |
JWT (JSON Web Token)
사용자 인증에 필요한 정보를 암호화된 토큰에 담아 클라이언트에게 발행하고, 클라이언트가 매 요청마다 이를 서버로 전송하는 방식.
특징
- Stateless (무상태): 서버가 사용자 정보를 별도로 저장할 필요가 없어 서버 확장이 용이하다. (세션 방식 한계 극복)
- 구조:
Header (토큰 타입/알고리즘) + Payload (클레임: 사용자 정보, 권한 등) + Signature (서명)
- 보안: 서명(Signature)을 통해 토큰이 변조되지 않았음을 확인하며, Payload는 암호화되지 않아 누구나 읽을 수 있으므로 민감한 정보는 넣지 않는다.
OAuth 2.0 (Open Authorization)
사용자 계정 정보(비밀번호 등)를 노출하지 않고, 제한된 권한을 다른 서비스(클라이언트)에 부여할 수 있도록 하는 권한 부여 프레임워크.
원리
Google, Facebook 등 자원 소유자 (Resource Owner)의 서비스에 직접 로그인하지 않고도, 해당 서비스가 관리하는 자원(프로필 정보 등)에 접근할 수 있는 접근 토큰 (Access Token, 주로 JWT 형태) 을 얻는 표준화된 절차를 제공한다.
주요 구성 요소
자원 소유자, 클라이언트 (접근 요청 앱/서비스), 권한 서버 (Authorization Server), 자원 서버 (Resource Server)
사용 예시 : 소셜 로그인 (네이버 로그인, 구글 로그인 등)
➕ OIDC (OpenID Connect)
OAuth 2.0은 ‘인가’ 프레임워크, OIDC는 OAuth 2.0 위에 구축된 ‘인증’ 레이어.
- 사용자의 신원(Identity) 정보를
ID Token 이라는 JWT 형태로 제공하여, OAuth가 아닌 인증의 목적에 초점을 맞춘다.
시스템 설계 예시
URL Shortener 시스템 설계
긴 URL을 짧은 URL로 변환하고, 짧은 URL로 요청이 오면 원래 URL로 리다이렉트(Redirect) 해주는 시스템.
핵심 기능
- URL 단축 (Shortening) : 긴 URL → 짧은 코드 (Short Code) 생성 및 저장.
- URL 리다이렉션 (Redirection) : 짧은 코드 → 긴 URL 조회 및 리다이렉션
단축 코드 생성 전략
가장 중요한 부분은 고유하고 짧은 Short Code를 생성하는 것.
ID 기반 (Base-62 인코딩)
- DB에 Auto-Increment ID를 기본 키로 사용해 저장한다.
- 이 ID (숫자)를 62진수(0-9, a-z, A-Z)로 변환하여 Short Code로 생성한다. (ex. ID 1000 → Short Code ‘g8’)
- 장점: 충돌 방지하여 고유성을 보장한다.
- 단점: ID의 순서가 노출되어 추측이 쉬울 수 있다.
랜덤 문자열/해시 기반
- 랜덤 문자열을 생성하거나, Long URL을 해시(ex. MD5, SHA-256) 후 일부를 잘라 Short Code를 만든다.
- DB에 해당 코드가 이미 있는지 확인하여 충돌 해소 로직이 필요하다.
시스템 구성 요소
- 클라이언트: 단축 URL 요청 및 클릭
- 로드 밸런서 (Load Balancer): 요청을 여러 웹 서버로 분산
- 웹 서버 (Web Server): 단축 및 리다이렉션 API 처리
- 데이터베이스 (DB): Long URL과 Short Code 매핑 정보 저장 (RDBMS or NoSQL)
- 캐시 (Cache): 자주 접근되는 Short Code의 Long URL을 저장하여 리다이렉션 속도 개선 (ex. Redis)
➕ 일관된 해싱 (Consistent Hashing)
분산된 캐시 시스템이나 데이터베이스에서 서버가 추가되거나 제거될 때, 데이터의 재분배를 최소화하여 시스템의 안정성과 효율성을 높이는 해싱 기법.
URL 단축기의 캐시 계층이나 데이터베이스 샤딩 (Sharding) 시 유용하게 고려될 수 있다.
채팅 시스템
실시간으로 메시지를 주고받는 시스템은 상태 유지와 실시간 통신이 핵심.
핵심 기술: WebSocket
- HTTP와 달리 클라이언트와 서버 간에 지속적인 양방향 통신 채널을 열어 실시간 데이터 전송을 가능하게 한다.
시스템 구성 요소
- 클라이언트: 사용자 기기 (브라우저, 모바일 앱)
- 로드 밸런서: 요청을 웹/API 서버로 분산
- 웹/API 서버: 인증/인가, 채팅방 생성 등 HTTP 요청 처리
- 채팅 서버 (WebSocket Server): WebSocket 연결 관리 및 실시간 메시지 처리
- 메시지 큐 (Message Queue): 메시지 전달의 안정성을 보장하고, 채팅 서버와 DB 간의 비동기 통신을 담당 (ex. Kafka, RabbitMQ)
- 데이터베이스 (DB): 채팅 기록, 사용자 정보, 채팅방 정보 저장
➕ 폴링 (Polling) & 롱 폴링 (Long Polling)
WebSocket이 등장하기 전이나, WebSocket 사용이 어려운 환경에서 사용되던 실시간 통신 기법.
- 폴링: 클라이언트가 일정 시간 간격으로 서버에 새 데이터가 있는지 계속 요청하는 방식 (비효율적)
- 롱 폴링: 클라이언트가 서버에 요청을 보내면, 서버는 새 데이터가 생길 때까지 연결을 유지했다가 데이터가 생기면 응답하고 연결을 끊는다. 클라이언트는 응답을 받잠자 다시 요청을 보낸다. (폴링보다 효율적)
표가 있어서 이해하기 좋았어요!