암호학: 치환기법, 전치기법
암호학 치환기법과 전치기법입니다. 시저 암호 수식, 단일 치환, Playfair, columnar transposition과 Python 실습 예제를 정리했습니다.
암호학: 치환기법, 전치기법
치환과 전치는 고전 암호를 이해할 때 가장 먼저 보는 두 가지 변환 방식이다. 치환은 문자를 다른 문자로 바꾸고, 전치는 문자의 위치를 바꾼다. 현대 암호는 훨씬 복잡하지만, 혼돈(confusion)과 확산(diffusion)을 설명할 때 이 두 개념이 기본 재료가 된다.
시저 암호
시저 암호는 알파벳을 일정한 간격만큼 밀어서 치환한다. 키가 3이면 a는 d, b는 e가 된다. 영문 알파벳 26자를 기준으로 하면 암호화와 복호화는 다음처럼 표현할 수 있다.
Encryption: C = E(p) = (p + k) mod 26
Decryption: p = D(C) = (C - k) mod 26plain : meet me after the toga party
key : 3
cipher: phhw ph diwhu wkh wrjd sduwb키 공간이 25개뿐이므로 시저 암호는 학습용으로만 다룬다. 공격자가 알고리즘을 알고 있고 평문 언어가 영어라는 사실까지 안다면 전수조사와 빈도 분석으로 쉽게 깨진다.
Python으로 시저 암호 확인
import string
ALPHABET = string.ascii_lowercase
def caesar(text: str, key: int) -> str:
out = []
for ch in text.lower():
if ch in ALPHABET:
idx = ALPHABET.index(ch)
out.append(ALPHABET[(idx + key) % 26])
else:
out.append(ch)
return "".join(out)
plain = "meet me after the toga party"
cipher = caesar(plain, 3)
restored = caesar(cipher, -3)
print(cipher)
print(restored)python3 caesar.py단일 치환 암호
단일 치환은 알파벳 전체를 임의의 치환표로 바꾼다. 시저 암호보다 키 공간은 훨씬 커지지만, 하나의 평문 문자가 항상 같은 암호문 문자로 바뀌기 때문에 언어의 빈도 특성이 남는다. 예를 들어 영어 문장에서는 e, t, a 같은 문자의 빈도가 높고, th, he, in 같은 이중자 패턴도 단서가 된다.
plain alphabet : abcdefghijklmnopqrstuvwxyz
cipher alphabet: qwertyuiopasdfghjklzxcvbnmPlayfair 같은 다중 문자 치환
Playfair는 두 글자씩 묶어 치환하는 방식이다. 5x5 표를 만들고, 보통 i와 j를 같은 칸으로 취급한다. 같은 행이면 오른쪽 글자로, 같은 열이면 아래 글자로, 둘 다 아니면 사각형의 반대 꼭짓점 글자로 치환한다.
keyword: monarch
m o n a r
c h y b d
e f g i k
l p q s t
u v w x z한 글자 단위 빈도 분석은 어렵게 만들지만, 긴 암호문에서는 여전히 구조가 남는다. 따라서 현대 보안 용도로 쓰는 방식은 아니다.
전치 기법
전치 암호는 글자를 바꾸지 않고 위치만 바꾼다. 예를 들어 열 개수를 6으로 잡고 문장을 행 단위로 채운 뒤, 열 순서를 1 4 2 5 3 6처럼 바꿔 읽을 수 있다.
key order: 1 4 2 5 3 6
plain : you need ream before the day beginsimport math
def columnar_transpose(text: str, order: list[int]) -> str:
clean = "".join(ch for ch in text.lower() if ch.isalpha())
width = len(order)
height = math.ceil(len(clean) / width)
padded = clean.ljust(width * height, "x")
rows = [padded[i:i + width] for i in range(0, len(padded), width)]
result = []
for col in order:
result.extend(row[col - 1] for row in rows)
return "".join(result)
print(columnar_transpose("you need dream before the day begins", [1, 4, 2, 5, 3, 6]))정리
- 치환은 값을 바꾸고, 전치는 위치를 바꾼다.
- 시저 암호는 수식 이해용으로 적합하지만 키 공간이 너무 작다.
- 단일 치환은 빈도 분석에 약하다.
- Playfair는 두 글자 단위라 단일 문자 빈도 분석은 어렵지만 현대 보안 기준에는 맞지 않는다.
- 현대 블록 암호는 치환과 전치 아이디어를 더 복잡한 라운드 구조 안에서 사용한다.