관리 메뉴

Bull

[Cryptography] Base64 파헤치기 본문

Computer Science/Cryptography

[Cryptography] Base64 파헤치기

Bull_ 2024. 3. 21. 20:14

개념

우선, 위키백과의 사전 정의를 보면

 

컴퓨터 분야에서 쓰이는 Base란 6비트 이진 데이터(예를 들어 실행 파일이나, ZIP 파일 등)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식을 가리키는 개념이다.

원래 Base 64를 글자 그대로 번역하여 보면 64진법이란 뜻이다. 특별히 64진법이 컴퓨터에서 흥미로운 것은, 64가 2의 제곱수(64 = 26)이며, 2의 제곱수들에 기반한 진법들 중에서 화면에 표시되는 ASCII 문자들을 써서 표현할 수 있는 가장 큰 진법이기 때문이다. 즉, 다음 제곱수인 128진법에는 128개의 기호가 필요한데 화면에 표시되는 ASCII 문자들은 128개가 되지 않는다.

그런 까닭에 이 인코딩은 전자 메일을 통한 이진 데이터 전송 등에 많이 쓰이고 있다. Base 64에는 어떤 문자와 기호를 쓰느냐에 따라 여러 변종이 있지만, 잘 알려진 것은 모두 처음 62개는 알파벳 A-Z, a-z와 0-9를 사용하고 있으며 마지막 두 개를 어떤 기호를 쓰느냐의 차이만 있다.

 

https://ko.wikipedia.org/wiki/%EB%B2%A0%EC%9D%B4%EC%8A%A464

 

베이스64 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 컴퓨터 분야에서 쓰이는 Base 64 (베이스 육십사)란 6비트 이진 데이터(예를 들어 실행 파일이나, ZIP 파일 등)를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의

ko.wikipedia.org

 

4년 전에 처음 봤을 때는 뭔소리인지 모르고 변환 도구로 되니까 그냥 썼었는데,

 

최근에 base64의 다른 버전인 base32를 재미있게 구현한 것이 기억나서 base64를 정리해보고 싶었다.

 

base64를 간단히 말하면...

'A'는 8bit(실제 사용은 7bit)를 사용하는 아스키코드에서는 10진법으로 65이고 65는 2진법으로 01000001이다.

( 'A' → 65 0100 0001)

 

만약 "AAA" 네자리가 연속으로 있다고 하고 이것을 2진법으로 바꾸면

 

"01000001 01000001 01000001"이 되는 것이다.

 

그러면 총 24자리가 되는데 이것을 다시 6bit로 나눠서 보는 것이다.

 

"010000 010100 000101 000001"

 

아래의 Base64 테이블에 매칭 시키면 다음과 같이 변환된다.

https://commons.wikimedia.org/wiki/File:Base_64_table_index.png
출처: https://commons.wikimedia.org/wiki/File:Base_64_table_index.png

 

"QUFB"

 

다시 과정을 하나하나 살펴보면,

 

<encode>

"AAA" → "65 65 65" → " 01000001 01000001 01000001" "010000 010100 000101 000001" →"QUFB"

 

<decode> (해체는 조립의 역순)

"QUFB" "010000 010100 000101 000001" " 01000001 01000001 01000001" "65 65 65" "AAA"

 

 

6과 8의 공배수로 나눠떨어지지 않을 경우...

위와 같은 경우는 24자리로 나눠떨어져서 6자리씩 끊어 읽는 게 가능했지만 그렇지 않은 경우가 있다.

 

그럴 땐, 간단하다.

 

남은 부분은 '0'으로 채우면 되는데 이를 패딩한다고 말할 수 있다.

 

예를들어,

 

"@@@@" → "64 64 64 64" "01000000 01000000 01000000 01000000"

→ "010000 000100 000001 000000 010000 00.."

 

는 6자리로 떨어지지 않으므로

 

→ "010000 000100 000001 000000 010000 000000"

→ "QEBAQA" ...

 

그런데, base64는 24bit 단위로 끊어서 전송하는 방식을 가지고 있어서 여기서 끝나지 않는다.

 

→ "010000 000100 000001 000000010000 000000 000000 000000"

→ "QEBAQA=="

 

이제 위에 처럼 패딩처리된 0은 "="으로 구분할 수 있다.

 

이에 대해 직관적으로 보기 좋은 규칙도 있다.

 

bit 마지막 부분 원본 자릿 수
 8bits == 1자리, 4자리, 7자리...
16bits = 2자리,5자리, 8자리...
24bits x 3자리,6자리,9자리...

 

 

헷갈리는 부분?

그런데 여기서 'A'와 '='이 똑같이 0으로 처리되는데 어떻게 구분하는 지 헷갈릴 수 있을 것이다.

 

금방 파헤쳐보면, 디코딩시 '='이라는 문자열을 받으면 무시하면 된다.

 

그러면 원본의 데이터만 읽을 수 있기 때문에 문제없다.

 

추천 연습 문제

https://dreamhack.io/wargame/challenges/1020

 

likeb64

Description 드림이가 base64를 공부하고 자신만의 암호를 만들었어요. 다음 주어진 암호문에서 플래그를 구해보세요! IREHWYJZMEcGCODGMMbTENDDGcbGEMJZGEbGEZTFGYaGKNRTMIcGIMBSGRQTSNDDGAaWGYZRHEbGCNRQMUaDOMbEMRTGEYJYGUaWGOJQM

dreamhack.io

 

base64를 직접 구현하는 것도 좋지만 비슷한 맥락으로 구현해볼 수 있는 문제가 있다.

 

매커니즘은 똑같으니 이 문제를 통해 base64를 완벽히 이해할 수 있으면 좋을 것 같다.

'Computer Science > Cryptography' 카테고리의 다른 글

[Cryptopgraphy] RSA 원리  (0) 2024.07.31