0 views
1. 개요 및 정의
1.1 한 줄 요약
- 인코딩은 데이터를 안전하게 운송하기 위해 규해진 규칙대로 포장(변환)하는 과정이며, 디코딩은 포장을 뜯어 원래의 내용물을 꺼내는 과정이다. 이는 비밀번호를 잠그는 '암호화'와는 근본적으로 다르다.
1.2 공식 정의
- 인코딩(Encoding):
- 정보의 형태나 형식을 표준화, 보안, 처리 속도 향상, 저장 공간 절약 등을 목적으로 다른 형태나 형식으로 변환하는 처리 방식이다.
- 디코딩(Decoding):
- 인코딩된 데이터를 다시 원래의 정보 형태로 되돌리는 역변환 과정이다.
- 주요 목적:
- 시스템 간 호환성:
- 서로 다른 시스템이 데이터를 주고받을 때 깨지지 않게 한다 (예: UTF-8).
- 전송 효율성 및 안전성:
- 바이너리 데이터를 텍스트 기반 프로토콜(HTTP, SMTP)로 전송 가능하게 한다 (예: Base64).
- 시스템 간 호환성:
2. 동작 원리 (Deep Dive)
- 인코딩은 적용 분야에 따라 문자 인코딩(Character Encoding)과 전송 인코딩(Transfer Encoding)으로 나뉜다.
- 이 두 가지 핵심 메커니즘을 상세히 분석한다.
2.1 문자 인코딩 (Character Encoding)
- 컴퓨터는 0과 1만 이해하므로, 사람이 사용하는 문자를 숫자로 매핑해야 한다.
- 문자 집합(Character Set): 문자에 고유한 번호(Code Point)를 부여하는 약속이다. (예: 'A' = 65)
- 인코딩 방식: 이 번호를 컴퓨터 메모리에 어떻게 비트(Bit)로 저장할지 결정하는 규칙이다.
- 대표적 예시: UTF-8
- 가변 길이: 문자에 따라 1바이트에서 4바이트까지 가변적으로 사용한다.
- 동작 방식:
- ASCII 문자(0~127): 1바이트만 사용 (
0xxxxxxx). - 다국어 문자: 첫 바이트에 바이트 수를 표시하는 헤더 비트가 들어간다 (예: 3바이트 문자 →
1110xxxx 10xxxxxx 10xxxxxx).
- ASCII 문자(0~127): 1바이트만 사용 (
- 엔디안(Endianness) 이슈 없음: 바이트 순서가 정해져 있어 BOM(Byte Order Mark)이 필수적이지 않다.
2.2 바이너리-텍스트 인코딩 (Base64)
- 이미지나 실행 파일 같은 바이너리 데이터를 텍스트만 처리 가능한 프로토콜(이메일 등)로 전송할 때 사용한다.
- 입력: 원본 데이터를 24비트(3바이트)씩 끊는다.
- 분할: 24비트를 6비트씩 4개로 쪼갠다 (6×4=24).
- 매핑: 각 6비트 값(0~63)을 Base64 색인표(A-Z, a-z, 0-9, +, /)에 매핑한다.
- 패딩: 원본 데이터가 3바이트로 나누어 떨어지지 않으면 끝에
=문자를 붙여 길이를 맞춘다.
3. 사용법 및 구문 (Syntax)
- 가장 범용적으로 사용되는 Python을 기준으로 인코딩과 디코딩을 시연한다.
3.1 문자열 인코딩 (String to Bytes)
-
문자열(
str)을 네트워크 전송이나 파일 저장을 위해 바이트(bytes)로 변환한다.# 원본 문자열 text = "안녕하세요" # 1. 인코딩 (UTF-8) # 문자를 UTF-8 바이트 시퀀스로 변환한다. encoded_bytes = text.encode('utf-8') print(f"Encoded: {encoded_bytes}") # 출력 예: b'\xec\x95\x88\xeb\x85\x95\xed\x95\x98\xec\x84\xb8\xec\x9a\x94' # 2. 디코딩 # 바이트 시퀀스를 다시 문자열로 복원한다. decoded_text = encoded_bytes.decode('utf-8') print(f"Decoded: {decoded_text}")
3.2 Base64 인코딩
-
바이너리 데이터를 ASCII 문자열로 변환한다.
import base64 # 바이너리 데이터 (예: "Python"의 ASCII 값) data = b'Python' # 1. Base64 인코딩 # 결과는 bytes 타입의 ASCII 호환 문자열이다. b64_encoded = base64.b64encode(data) print(f"Base64 Encoded: {b64_encoded}") # 출력: b'UHl0aG9u' # 2. Base64 디코딩 b64_decoded = base64.b64decode(b64_encoded) print(f"Base64 Decoded: {b64_decoded}")
3.3 URL 인코딩 (Percent Encoding)
-
URL에 포함될 수 없는 특수 문자나 공백을 변환한다.
import urllib.parse # 쿼리 파라미터 query = "이름=홍길동&직업=개발자" # 1. URL 인코딩 url_encoded = urllib.parse.quote(query) print(f"URL Encoded: {url_encoded}") # 출력: %EC%9D%B4%EB%A6%84%3D%ED%99%8D%EA%B8%B8%EB%8F%99%26%EC%A7%81%EC%97%85%3D%EA%B0%9C%EB%B0%9C%EC%9E%90 # 2. URL 디코딩 url_decoded = urllib.parse.unquote(url_encoded) print(f"URL Decoded: {url_decoded}")
4. 심화 및 보안 (Advanced & Security)
4.1 인코딩은 암호화가 아니다
- 인코딩:
- 알고리즘(규칙)만 알면 누구나 원본을 복구할 수 있다.
- 기밀성(Confidentiality)을 제공하지 않는다.
- 암호화:
- 키(Key)가 있어야만 복호화할 수 있다.
- 보안 권고:
- 비밀번호나 개인정보를 Base64로만 인코딩하여 저장하거나 전송해서는 안 된다.
- 반드시 해시(Hash)하거나 암호화해야 한다.
4.2 보안 장비 우회 (WAF Evasion)
- Double Encoding:
- 공격 코드를 두 번 인코딩하여 WAF가 1차 디코딩만 수행하고 검사할 때 통과한 뒤, 애플리케이션 내부에서 2차 디코딩되어 실행되게 하는 기법이다.
- 예: → %3Cscript%3E (1차) → %253Cscript%253E (2차)
- 방어 대책:
- 입력값을 디코딩한 후 정규화(Normalization) 과정을 거쳐 검증해야 한다.
- 순환 디코딩을 통해 더 이상 변하지 않을 때까지 디코딩한 후 패턴을 매칭해야 한다.
'Etc'카테고리의 다른 글
Loading comments...