XOR = (배타적 논리합) 암호학

코딩 파인애플·2026년 8월 11일

CRYPTOGRAPHY

목록 보기
2/4
post-thumbnail

안녕하십니까 코딩 파인애플입니다
이번 시간에는 XOR 베타적 논리합에 관해 알아보겠습니다.

❌⭕R 이란?

사실 코딩 파인애플은 이 XOR 베타적 논리합 암호학에 관해 꽤 안좋은 기억이 있습니다...

때는 바야흐로 병오년(丙午年) 임진(壬辰)월...예, 그냥 2026년 4월.

그때쯤 사이버보안 경진대회 CTF 비스므리한 거에 참가했는데
CTF 암호학 문제 중 XOR 관련한 문제, 그 "한 문제"를 못 풀어서 정ㅗㅗㅗ말 아쉽게도❗❗❗4+♿️+등,❗+♿️+장❗+♿️+려❗+♿️+❗상+♿️+을❗❗❗ 입상한 빌어먹을 추억이 있었습니다
(3등과 XOR 겨우 한 문제 차이였습니다 사실 저의 무지가 한 몫 했죠.)


아무톤톤간에, 다시 본론으로 넘어가자면

XOR(Exclusive OR)은 배타적 논리합 약자입니다

두 개의 입력값이 서로 다를 때만 1을 출력하고, 서로 같으면 0을 출력하는 논리 연산입니다

# 프로그래밍에서는 비트 연산자 (^)가 주로 사용됩니다
0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0

또한 XOR는 다음과 같은 대칭성을 가집니다

평문(A) ⊕ 키(K) = 암호문(B)

암호문(B) ⊕ 키(K) = 평문(A)

즉, 데이터를 암호화할 때 사용한 키를 그대로 사용해 한 번 더 XOR 연산을 하면 원래의 데이터가 완벽하게 복호화됩니다.

코드 ㄱㄱ

XOR의 대수적 성질 이용해 암호문을 구상하면

KEY1 = a373807b0cceafa26a2631bd25
KEY2 ^ KEY1 = 485d7d25d563edbb8735d213bb
KEY2 ^ KEY3 = 9856e2e7f6c0716e20b737b209
FLAG ^ KEY1 ^ KEY3 ^ KEY2 = 73400ef09522fe9b25e36a6b0d

을 복호화하는 코드를 짜보면

key1 = bytes.fromhex("a373807b0cceafa26a2631bd25")
key12 = bytes.fromhex("485d7d25d563edbb8735d213bb")
key23 = bytes.fromhex("9856e2e7f6c0716e20b737b209")
key123 = bytes.fromhex("73400ef09522fe9b25e36a6b0d")

# bytes.fromhex() : 16진수 문자열을 입력받아 바이트 객체로 변환해 주는 메서드

key2 = ""
for i, j in zip(key1, key12):
    key2 += chr(i ^ j)

key3 = ""
for i, j in zip(key2, key23):
    key3 += chr(ord(i) ^ j)

flag = ""
for i, j, l, k in zip(key1, key2, key3, key123):
    flag += chr(i ^ ord(j) ^ ord(l) ^ k)

print(flag)


또한 기타 암호문을 05080407411f0741134205000b0f194203131015170c051710, 키는 bar이라 가정할 때 평문을 알기 위해

output = bytes.fromhex("05080407411f0741134205000b0f194203131015170c051710")

key = b"bar"
# b"" : 파이트 타입임을 의미
flag = ""
idx = 0
# 각 문자마다 "bar"를 순회하여 XOR 연산.
for i in output:
    flag += chr(i ^ key[idx % len(key)])
    
    idx += 1
print(flag)

다음과 같은 코드를 거쳐 평문을 얻을 수 있습니다


그 외에도 6548404f495e4345440b 암호문을 브루트포스를 통해 0부터 255까지 XOR 돌려주면

output = bytes.fromhex("6548404f495e4345440b")
for i in range(256):
    flag = ""
    for j in output:
        flag += chr(i ^ j)
    
    chk = True
    for c in flag:
        if not (32 <= ord(c) < 127):
            chk = False
            break
    
    if chk: print(flag)

등등과 같은 XOR 유형이 있겠습니다


한번 배웠던 내용을 실습해봅시다 : https://dreamhack.io/wargame/challenges/3014


이상으로 글을 마치겠습니다 감사합니다

영역전개(ڈومین ایکسپینشن) : 미군버스터(امریکی فوج کا 'بسٹر')

profile
안녕하떼요취미로콤푸타배우는고든학교6학년유치원생이빈다주말재외하고(러블럭스해야대요💢💢)주중연재하고안한날애눈이월(February)됨니다(안할수도있음)

0개의 댓글