← 온라인 안전
ASTERXOR / 온라인 안전

뒤섞인 글자가 곧 암호화는 아니다

Base64는 바이트를 텍스트로 운반하기 편하게 만든다. 낯선 모습 때문에 이 평범한 기능이 비밀스러운 보호처럼 보일 수 있다.

일반 문장과 Base64 표현이 키 없는 변환으로 연결된 그림.
실제로 실행한 것은 가상의 무해한 문장에 대한 Base64 변환뿐이다. 암호화 시스템은 만들거나 시험하지 않았다.
온라인 안전ASTERXOR / LEON LEUNG

비밀 없이 누구나 되돌릴 수 있다면, 무엇을 보호하는 변환일까?

문자와 숫자가 뒤섞인 문자열은 한눈에 읽히지 않는다는 이유만으로 비공개처럼 느껴진다. 하지만 소프트웨어는 비밀을 지키기 위해서가 아니라 전송을 위해 데이터의 표현을 바꾸는 경우가 많다. 저장된 값, QR 내용, 첨부 파일을 볼 때 이 구분은 중요하다. 낯선 텍스트는 형식을 확인할 이유이지, 내용이 기밀이라는 증거가 아니다.

다른 문자 체계가 접근 규칙을 만들지는 않는다.
A USEFUL CONVERSION

소프트웨어가 문자 체계를 바꾸는 이유

어떤 시스템은 텍스트를 기대하는 통로로 임의의 바이트를 전달해야 한다. Base64는 비트 묶음을 정해진 출력 가능한 문자로 표현한다. 특정 메시지와 형식 안에 데이터를 넣기 쉬워지는 것이다. 같은 수를 다른 표기법으로 적듯 값을 유지하면서 표현을 바꾸는 유용한 기본 기능이다.

규칙은 공개되어 있고 디코딩에 비밀은 필요하지 않다. 인코딩된 값과 호환 디코더가 있으면 원래 바이트를 복원할 수 있다. 암호화된 바이트를 Base64로 감쌀 수는 있지만, Base64 때문에 암호화되는 것은 아니다. 보호가 있다면 표현을 바꾸기 전에 이루어진 별도의 연산에서 나온다.

공개된 문자 변환표를 떠올리면 구분하기 쉽다. 쓰는 방식을 바꾸면 채널로 전달하기 편하지만 표를 가진 누구나 원문을 읽을 수 있다. 접근 제한에는 다른 장치가 필요하다. Base64는 진짜 보안 시스템의 무작위처럼 보이는 값과 닮아 특히 오해하기 쉽다.

TRY THE SMALL CASE

스물두 바이트의 왕복

가상의 문장 “Meet by the blue tree.”를 로컬에서 인코딩했다. ASCII 22바이트가 Base64 32문자로 바뀌었다. 그 출력을 디코딩하자 비밀번호나 키 없이 원래 22바이트가 정확히 돌아왔다. 바이트를 직접 비교했으므로 표시된 문장이 단지 비슷해 보이는지에 의존한 결과가 아니다.

작은 예시 세 개는 패딩을 보여 준다. M은 TQ==, Ma는 TWE=, Man은 TWFu가 되며 출력은 모두 네 문자다. 표준 패딩 표현에서 등호는 불완전한 묶음을 채우는 것이지 비밀번호 표시가 아니다. 네 번의 왕복 모두 성공했다.

M, Ma, Man과 가상 문장의 바이트 수, Base64 문자열, 출력 길이를 보여 주는 표.
FIG 01무해한 입력 네 개가 정확히 복원됐다. 22바이트 문장은 32문자가 됐다.
READ THE SHAPE CAREFULLY

문자가 늘어도 보호가 늘지는 않는다

표준 패딩 Base64의 길이는 입력을 3바이트씩 묶고 남는 부분을 한 묶음으로 올림한 뒤 4를 곱한 값이다. 짧은 예시와 긴 문장의 길이를 모두 설명한다. 늘어난 문자는 표현 방식의 추가 비용이지, 보안성이나 무작위성이 얼마나 좋아졌는지 측정한 값이 아니다.

스크립트는 엄격한 디코딩을 요청했을 때 잘못된 문자도 거부했다. 이는 입력이 기대한 형식을 따르는지 확인할 뿐, 누가 보냈는지나 내용이 안전한지를 증명하지 않는다. 올바른 인코딩 안에도 잘못된 정보, 공개 정보, 비공개 정보, 유해한 내용이 들어갈 수 있다. 문법만으로 구분할 수는 없다.

공식이 세는 것은 화면의 글자가 아니라 입력 바이트다. 원래 문장은 ASCII라 문자마다 한 바이트였지만 다른 문자 체계나 악센트가 있는 라틴 문자도 더 필요할 수 있다. 길이를 말하기 전에 문자 인코딩을 밝혀야 서로 다른 단위를 세면서 같은 문자를 센다고 생각하는 일을 피한다.

SEPARATE THE JOBS

기밀성은 다른 질문에 답한다

올바른 암호화는 암호학적 키와 적절한 설계를 사용해 필요한 접근 권한이 없는 사람이 내용을 얻지 못하게 한다. 인증과 무결성 기법은 누가 만들었고 바뀌었는지를 다룬다. 현대적인 인증 암호화는 중요한 보호를 결합할 수 있지만, 이를 선택하고 구현하는 일은 즉석 문자 치환으로 해결할 일이 아니다.

해시는 또 다른 일을 한다. 정확한 내용을 신뢰할 수 있는 예상값과 비교할 수 있도록 요약값을 만든다. 일반적으로 디코딩해서 원문으로 되돌리지 않으며, 다른 곳에 저장된 원본 내용을 그 자체로 숨기지도 않는다. 유용한 보안은 가장 읽기 어려운 출력을 고르는 것이 아니라 요구에 맞는 기법을 쓰는 데서 나온다.

보호 주장은 흐름의 구체적인 부분에 붙여 두자. 파일이 암호화된 연결을 지나 목적지에서 읽을 수 있는 텍스트로 저장되고 내보내기에서는 Base64로 표시될 수 있다. 세 설명은 동시에 참일 수 있다. 어느 사본, 어느 단계, 누구에게 보이는지 물어야 안심되는 단어 하나를 전체 과정으로 확대하지 않는다.

인코딩, 암호화, 인증이 각각 어떤 질문에 답하는지 설명하는 세 카드.
FIG 02개념 그림은 표현, 기밀성, 진위 확인을 구분한다. 실행한 것은 인코딩뿐이다.
DO NOT GUESS FROM APPEARANCE

같은 포장에 다른 내용이 든다

Base64처럼 보이는 값 안에는 평문, 이미지, 구조화된 메시지, 암호문이 들어갈 수 있다. 읽을 수 있는 필드를 가진 토큰도 별도 서명으로 무결성을 보호할 수 있다. 일부가 읽힌다고 공유해도 안전한 것은 아니다. 쉽게 디코딩되는 부분이 있어도 전체 값이 접근 권한을 줄 수 있다.

호기심 때문에 낯선 계정 값을 온라인 디코더에 붙여 넣지 말자. 필요하다면 서비스 문서와 신뢰할 수 있는 로컬 검사 방법을 이용해야 한다. 이번 예시는 실험을 위해 만든 문장뿐이다. 세션 토큰, 복구 코드, 예시 자격 증명이 아니며 어떤 계정 자료도 살펴보지 않았다.

안전한 확인은 계정에서 복사한 미지의 값 대신 연습용으로 직접 쓴 글에서 시작한다. 로컬에 원래 바이트를 보관하고 해독 결과와 정확히 비교한다. 형식을 모르거나 접근 권한을 줄 수 있는 값이라면 멈추고 발급자의 문서를 보자. 호기심은 그런 값을 온라인 해독 서비스에 보낼 이유가 아니다.

A CLOSER CHECK

글자, 바이트, 문자 집합을 나누어 보자

두 번째 표본 café를 UTF-8로 인코딩했다. 이 표기의 Unicode 코드 포인트는 넷이지만 UTF-8은 다섯 바이트다. 표준 Base64 결과 Y2Fmw6k=는 여덟 문자이며 해독하면 원문이 돌아온다. 늘어난 바이트는 악센트 문자의 표현이지 추가 비밀성이 아니다. 코드 포인트 수도 눈에 보이는 글자 수의 보편적 기준은 아니다.

다음으로 16진수 FB FF라는 무해한 두 바이트를 비교했다. 표준 Base64는 +/8=, URL 안전 변형은 -_8=로 쓴다. 각각 맞는 디코더를 사용하면 같은 두 바이트가 나온다. 기호 차이는 담는 형식에 맞추기 위한 것이다. 어느 표현도 기밀성이나 보낸 사람의 신원에 대한 증거를 더하지 않는다.

따라서 외형으로 형식을 짐작하는 것은 출발점일 뿐이다. 프로토콜마다 패딩이나 주변 구조도 정할 수 있다. 문서가 정한 디코더를 따르고 검증하려면 결과 바이트를 비교한다. 추가 여덟 검사는 이 표본만 다루며 모든 관대한 디코더나 토큰 형식을 시험하지 않았다.

café는 코드 포인트 넷, UTF-8 다섯 바이트, Base64 여덟 문자다. 두 문자 집합은 같은 FB FF 바이트를 나타낸다.
FIG 03café는 코드 포인트 넷, UTF-8 다섯 바이트, Base64 여덟 문자다. 두 문자 집합은 같은 FB FF 바이트를 나타낸다.
ASK FOR THE PROPERTY

모호한 이름 대신 구체적인 질문

제품이 정보를 보호한다고 말하면 어떤 속성인지 물어보자. 연결이 암호화되는가? 저장 사본도 암호화되는가? 누가 키를 보유하며 누가 내용을 읽을 수 있는가? 이런 질문은 시스템과 접근 경계를 설명한다. 뒤섞인 글자의 스크린샷만으로는 어느 것도 답할 수 없다.

문서를 공유하는 간단한 일이라면 이름을 바꾸거나 내용을 인코딩하기보다 보호와 공유 설정이 명확한 검증된 도구를 쓰자. 수신자와 실제로 보낼 사본도 확인해야 한다. 인코딩은 제 이름으로 부를 때 여전히 유용하다. 비밀을 보장하지 않고 바이트를 가역적으로 전달하는 방식이다.

관찰한 키 없는 디코딩과 시험하지 않은 기밀성을 구분하고 키와 접근에 관한 질문을 제시하는 카드.
FIG 04예시는 키 없는 왕복을 증명할 뿐, 다른 시스템의 암호화 여부를 판단하지 않는다.

더 읽어 보기

RFC 4648: Base encodings ↗Python documentation: Base64 ↗NIST: securing data and devices ↗

공식 문서와 함께 읽으면 좋은 자료입니다.

가져갈 생각 하나

문자가 옷을 갈아입으면 안에서 무엇이 달라졌는지 묻자. 같은 바이트를 적는 방식만 바뀌었다는 것이 정직한 답일 때도 있다.