일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- HTML
- 코드트리
- Java
- 자바스크립트
- 리액트
- JavaScript
- userprog
- Flutter
- 핀토스
- 자바
- defee
- pintos
- Vue.js
- 알고리즘
- 백준
- corou
- 티스토리챌린지
- 오블완
- 크래프톤 정글
- TiL
- 시스템콜
- 사이드프로젝트
- 4기
- 스택
- 큐
- CSS
- 크래프톤정글
- 소켓
- 모션비트
- 나만무
- Today
- Total
미새문지
24.08.01 day38 Base64 인코딩, 패스워드를 전송하고 보관하는 방법 본문
Base64 인코딩
Base64 인코딩은 바이너리 데이터를 ASCII 텍스트로 변환하는 인코딩 방식이며, 이는 데이터를 텍스트 기반 시스템(예: 이메일, JSON, XML 등)에서 쉽게 전송하고 저장할 수 있도록 하기 위해 사용된다.
Base64는 바이너리 데이터를 텍스트로 변환할 때 데이터 크기를 약 33% 정도 증가시킨다.
인코딩 과정
- 바이너리 데이터 분할: 원본 바이너리 데이터를 3바이트(24비트)씩 나눈다.
- 비트 그룹 변환: 각 3바이트 블록을 6비트씩 4개의 그룹으로 나눕니다. 6비트는 2^6 = 64개의 값(0부터 63까지)을 가질 수 있다.
- Base64 인덱스 매핑: 각 6비트 그룹을 Base64 인덱스 테이블의 값으로 변환하는데, 이 테이블은 " A-Z (0-25)", "a-z (26-51)", "0-9 (52-61)", "+ (62)", "/ (63)"의 문자 집합을 가진다.
- 패딩 추가: 원본 데이터의 길이가 3의 배수가 아닐 경우, 남은 바이트를 처리하기 위해 '=' 문자를 사용하여 패딩을 추가한다.
디코딩 과정
Base64로 인코딩된 문자열을 디코딩하는 과정은 인코딩의 역순이다
- 패딩 제거: 문자열 끝에 있는 '=' 문자를 제거
- Base64 인덱스 역매핑: 각 문자에 대해 Base64 인덱스 테이블을 사용하여 6비트 값으로 변환
- 비트 병합: 6비트 그룹을 다시 8비트(1바이트) 그룹으로 병합
- 바이너리 데이터 재구성: 병합된 비트를 원본 바이너리 데이터로 복원
예제
"hello"라는 문자열을 Base64로 인코딩하는 예제이다.
1. 바이너리 데이터: "hello"의 ASCII 값은 104 101 108 108 111
2. 2진수 변환: 각 바이트를 8비트 2진수로 변환
104 -> 01101000
101 -> 01100101
108 -> 01101100
108 -> 01101100
111 -> 01101111
3. 3바이트 그룹화 및 6비트 분할
01101000 01100101 01101100 -> 011010 000110 010101 101100
01101100 01101111 -> 011011 000110 1111 (남은 4비트는 0으로 패딩)
4. Base64 인덱스 매핑
011010 -> a
000110 -> G
010101 -> V
101100 -> s
011011 -> b
000110 -> G
111100 -> 8 (추가된 0비트 포함)
결과적으로, "hello"는 "aGVsbG8="로 인코딩된다.
활용 사례
- 이메일 첨부파일: MIME(Multipurpose Internet Mail Extensions)에서 바이너리 파일을 텍스트로 인코딩하기 위해 사용된다.
- 데이터 URI 스키마: 이미지를 Base64로 인코딩하여 HTML/CSS에 직접 포함시킬 수 있다.
- 웹 API: JSON 및 XML과 같은 텍스트 포맷으로 바이너리 데이터를 주고받을 때 사용된다.
Base64 인코딩은 데이터를 안전하고 호환성 있게 전송하기 위해 널리 사용되며, 특히 텍스트 기반 시스템에서 유용할 수 있다.
사용자 패스워드를 전송하고 보관하는 방법
사용자 패스워드를 전송하고 보관하는 것은 보안에 있어서 매우 중요한 문제인데, 이를 안전하게 처리하기 위해 여러 가지 기술을 사용할 수 있다.
패스워드 전송 방법
- HTTPS 사용
- 패스워드를 전송할 때는 항상 HTTPS(SSL/TLS)를 사용하여 전송해야 하며, HTTPS는 데이터가 전송되는 동안 도청 및 변조를 방지할 수 있다.
- HTTPS를 사용하면 클라이언트와 서버 간의 통신이 암호화되어 네트워크를 통한 패스워드 유출 위험이 줄어든다.
- 전송 중 암호화
- 패스워드를 전송하기 전에 클라이언트 측에서 암호화할 수 있으며, 이를 통해 서버로 전송되는 패스워드가 더 안전하게 보호된다.
- 그러나 서버가 암호화된 패스워드를 복호화해야 하는 경우, 서버 측의 보안 관리가 더 복잡해질 수 있다.
패스워드 보관 방법
해싱(Hashing)
- 패스워드를 원문 그대로 보관하는 것은 매우 위험하기 때문에, 패스워드를 해시 함수로 변환하여 저장한다.
- 강력한 해시 함수 사용: SHA-256, SHA-3 등의 강력한 해시 함수를 사용한다. MD5, SHA-1 등은 안전하지 않으므로 사용하지 않는다.
- 솔팅(Salting): 해시 함수에 솔트를 추가하여 해시를 생성한다. 솔트는 각 사용자마다 고유한 값으로, 같은 패스워드라도 다른 해시값을 가지도록 할 수 있으며, 이를 통해 무차별 대입 공격 및 레인보우 테이블 공격을 방어할 수 있다.
- 페퍼링(Peppering): 솔트와 유사하지만, 서버에 저장하지 않고 애플리케이션 코드에 내장된 비밀 값을 추가로 사용한다.
예시
import bcrypt
# 패스워드 해싱
password = b"super_secret_password"
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
# 패스워드 검증
def check_password(stored_hash, user_password):
return bcrypt.checkpw(user_password, stored_hash)
KDF(Key Derivation Functions)
- 해시 함수 대신 패스워드 기반 키 도출 함수(PBKDF2, scrypt, Argon2 등)를 사용하며, 이는 반복적으로 해시를 적용하여 계산을 더 복잡하게 만들어 무차별 대입 공격을 어렵게 한다.
- Argon2: 현재 가장 추천되는 패스워드 해싱 알고리즘 중 하나이다.
예시
from argon2 import PasswordHasher
# 패스워드 해싱
ph = PasswordHasher()
hashed_password = ph.hash("super_secret_password")
# 패스워드 검증
def check_password(stored_hash, user_password):
try:
ph.verify(stored_hash, user_password)
return True
except VerificationError:
return False
추가 보안 방법
- 이중 인증(Two-Factor Authentication, 2FA)
- 패스워드 외에 추가적인 인증 수단을 사용하여 보안을 강화한다.
- 예를 들어, SMS 코드, OTP(One-Time Password) 앱 등을 사용할 수 있다.
- 계정 잠금(Account Lockout)
- 일정 횟수 이상 잘못된 로그인 시도를 할 경우 계정을 잠금 처리하여 무차별 대입 공격을 방어한다.
- 주기적인 패스워드 변경
- 사용자가 주기적으로 패스워드를 변경하도록 유도하여 보안을 강화한다.
- 패스워드 정책
- 강력한 패스워드 정책을 설정하여 사용자가 최소한의 복잡성을 가지는 패스워드를 사용하도록 한다.
- 예를 들어, 최소 8자 이상, 대문자, 소문자, 숫자, 특수문자 포함 등의 거지같은 패스워드 정책을 따른다.
사용자 패스워드의 전송과 보관은 매우 중요한 보안 문제이며, HTTPS를 사용하여 전송을 암호화하고, 안전한 해시 함수 및 KDF를 사용하여 패스워드를 해싱하여 저장하는 것이 기본적인 보안 방법이다. 또한 추가적인 보안 방법을 함께 사용하여 보안을 강화할 수 있다.
'개발 TIL' 카테고리의 다른 글
24.08.05 day40 IIFE, Type과 Interface의 차이점 (0) | 2024.08.05 |
---|---|
24.08.02 day39 OOP, Bootstrap (0) | 2024.08.02 |
24.07.31 day37 리덕스를 사용하는 이유, 리덕스의 3대 원칙, 내려가기 (0) | 2024.07.31 |
24.07.30 day36 DHCP, 슬라이딩 윈도우 (0) | 2024.07.30 |
24.07.29 day35 소켓, TCP/UDP (0) | 2024.07.29 |