🕵️ 친구와 암호 대화
한국어

암호화·해시·인코딩의 차이

"그 파일은 base64로 암호화되어 있어요", "비밀번호는 해시로 암호화해서 저장합니다" 같은 말을 들어 보신 적이 있을 것입니다. 일상에서는 이 세 단어가 섞여 쓰이지만, 정보 보안에서는 완전히 다른 도구입니다. 하나는 비밀을 지키기 위한 것이고, 하나는 지문을 만들기 위한 것이며, 나머지 하나는 단지 포장 방식을 바꾸는 것입니다. 이 글에서는 세 개념을 각각 다른 일상의 물건에 빗대어 구별하고, 어떤 상황에서 무엇을 써야 하는지 정리합니다.

인코딩: 내용을 가리지 않고 모양만 바꿉니다

인코딩은 데이터를 다른 환경에서 다룰 수 있게 모양을 바꾸는 일입니다. 한글을 컴퓨터에 저장하려면 UTF-8 같은 규칙으로 바이트로 바꿔야 하고, 이미지를 이메일 본문에 실어 보내려면 글자만으로 표현되는 형태로 바꿔야 합니다. 이때 쓰는 대표적 방식이 base64입니다. 3바이트를 4개의 글자(영문 대소문자, 숫자, 기호 두 개)로 바꾸기 때문에 결과가 원래보다 약 3분의 1 길어집니다.

핵심은 인코딩에는 열쇠가 없다는 점입니다. 규칙이 공개되어 있으므로 누구든 되돌릴 수 있습니다. 비유하자면 편지를 다른 나라 우편 규격의 봉투에 옮겨 담는 것과 같습니다. 봉투 모양은 달라졌지만 편지는 그대로 들어 있고, 누구든 봉투를 열면 읽을 수 있습니다. 이 서비스의 URL에 들어 있는 키 부분이나 비밀어의 영문숫자 모양도 base64url이라는 인코딩으로 적은 것입니다. 이는 바이트를 글자로 옮겨 적은 표기일 뿐, 그 자체가 보호 장치는 아닙니다. 보호는 그 안의 바이트가 AES-GCM으로 암호화되어 있다는 사실에서 나옵니다.

그래서 "base64로 암호화했다"는 표현은 틀린 말입니다. 로그인 정보를 base64로 적어 두고 안전하다고 생각하는 설정 파일을 종종 볼 수 있는데, 이는 문을 잠그지 않고 문 위에 "잠김"이라고 써 붙인 것과 같습니다. 인터넷에서 base64 변환 사이트를 열면 몇 초 만에 원문이 나옵니다.

암호화: 열쇠가 있는 사람만 되돌릴 수 있습니다

암호화는 키라는 비밀값을 사용해 데이터를 알아볼 수 없게 만들고, 같은 키(또는 짝이 되는 키)를 가진 사람만 원래대로 되돌릴 수 있게 하는 일입니다. 핵심은 양방향이라는 점입니다. 잠갔으니 열 수 있어야 합니다. 받는 사람이 내용을 읽어야 하는 모든 상황에서 쓰입니다. 메신저 대화, 파일 보관, 웹사이트 접속(HTTPS) 모두 해당합니다.

비유하면 자물쇠가 달린 상자입니다. 상자의 구조는 공개되어 있어도(AES처럼 알고리즘은 누구나 읽을 수 있습니다) 열쇠를 모르면 열 수 없어야 합니다. 그래서 암호의 안전성은 "방식을 숨기는 것"이 아니라 "키를 지키는 것"에 달려 있습니다. 이 원칙을 지키지 않고 자기만의 비밀 규칙으로 글자를 바꾸는 방식은 결국 인코딩에 가깝고, 전문가가 분석하면 대체로 풀립니다. 현대적인 암호화가 실제로 어떻게 동작하는지는 AES-GCM 쉽게 풀어쓰기에서 자세히 다룹니다.

암호화에서 키가 어디서 오는지도 중요합니다. 사람이 외우는 비밀번호는 길이가 짧고 예측 가능해서 그대로 키로 쓰기 어렵습니다. 그래서 비밀번호를 일부러 느린 계산에 여러 번 통과시켜 키로 만드는 과정(키 유도)을 거칩니다. 이 서비스에서 비밀번호를 쓸 때 PBKDF2를 600000번 반복하는 것이 그런 과정입니다. 이 과정에서 해시 함수가 재료로 쓰입니다. 이제 해시가 무엇인지 보겠습니다.

해시: 되돌릴 수 없는 지문을 만듭니다

해시 함수는 어떤 길이의 입력이든 고정된 길이의 값(해시값)으로 줄여 주는 함수입니다. 예를 들어 SHA-256은 입력이 한 글자든 영화 한 편이든 항상 256비트(32바이트) 결과를 냅니다. 같은 입력은 언제나 같은 결과가 나오고, 입력이 아주 조금만 달라져도 결과는 완전히 달라집니다. 그리고 결과만 보고 원래 입력을 거꾸로 알아내기는 매우 어렵도록 설계됩니다. 즉 해시는 단방향입니다.

비유하자면 사람의 지문입니다. 지문으로 그 사람이 맞는지 확인할 수는 있지만, 지문만 보고 그 사람의 얼굴과 키를 복원할 수는 없습니다. 그래서 해시는 "내용을 숨기는" 용도가 아니라 "같은지 확인하는" 용도로 씁니다. 대표적인 쓰임은 두 가지입니다. 하나는 파일 무결성 확인입니다. 내려받은 프로그램의 해시값이 배포처가 공개한 값과 같다면 중간에 바뀌지 않은 것입니다. 다른 하나는 비밀번호 저장입니다.

비밀번호는 왜 암호화가 아니라 해시로 저장할까요

서비스가 비밀번호를 암호화해서 저장한다면, 그 암호를 푸는 키도 어딘가에 있어야 합니다. 서버가 침해당하면 키와 암호문이 한꺼번에 털려 모든 비밀번호가 드러날 수 있습니다. 반대로 해시로 저장하면 로그인할 때 입력한 비밀번호를 같은 방식으로 해시해서 저장된 값과 비교만 하면 됩니다. 서비스 운영자조차 원래 비밀번호를 알 필요가 없습니다.

다만 그냥 해시만 하면 충분하지 않습니다. 사람들이 자주 쓰는 비밀번호는 한정되어 있어서, 공격자가 흔한 비밀번호 수억 개의 해시를 미리 계산해 두고 대조하면 금방 맞출 수 있기 때문입니다. 그래서 두 가지 장치를 더합니다. 첫째, 사용자마다 다른 무작위 값인 솔트를 섞어서 미리 계산해 둔 표를 못 쓰게 합니다. 둘째, 의도적으로 느리게 설계된 함수(bcrypt, scrypt, Argon2, PBKDF2 같은 것들)를 씁니다. 한 번의 확인은 눈 깜짝할 사이지만, 수억 번 대입하려는 공격자에게는 엄청난 시간이 되도록 만드는 것입니다. 빠른 범용 해시(MD5, SHA-1 같은 것)를 비밀번호 저장에 그대로 쓰는 것은 권장되지 않습니다. 참고로 MD5와 SHA-1은 서로 다른 입력이 같은 해시값을 내는 충돌을 만들 수 있다는 점이 입증되어, 보안 용도에서는 이미 물러난 알고리즘입니다.

세 가지를 한눈에 구분하는 질문

헷갈릴 때는 이렇게 물어보시면 됩니다.

세 가지는 한 시스템 안에서 함께 쓰이기도 합니다. 예컨대 이 서비스는 글을 AES-GCM으로 암호화하고, 그 결과 바이트를 읽고 옮기기 쉽도록 한글 또는 영문숫자 모양으로 인코딩하며, 비밀번호로부터 키를 만들 때는 해시 기반 함수(PBKDF2, HKDF)를 씁니다. 서버에는 비밀번호 인증 토큰의 해시만 저장됩니다. 이렇게 섞여 있기 때문에 일상에서 용어가 혼동되기 쉽습니다.

자주 하는 오해 몇 가지

"해시를 암호화한 것이니 복호화하면 되지 않나요?"라는 질문을 가끔 받는데, 해시는 복호화라는 개념이 없습니다. 입력의 정보 대부분이 버려지기 때문입니다. 다만 짧고 흔한 입력이라면 후보를 하나씩 넣어서 같은 해시가 나오는지 맞춰 보는 방식으로 사실상 알아낼 수는 있습니다. 이것이 비밀번호가 충분히 길고 무작위여야 하는 이유입니다. 이에 대해서는 강한 비밀번호와 암호문을 만드는 법에서 이어서 다룹니다.

또 하나, "암호화했으니 변조는 걱정 없다"는 생각도 정확하지 않습니다. 암호화 방식에 따라 내용이 바뀌었는지 알아채지 못하기도 하므로, 요즘은 위변조 검출까지 함께 하는 방식을 씁니다. 말하자면 암호화·해시·인코딩은 서로 대체할 수 없고, 각자 맡은 일이 다른 도구입니다. 이 구분만 머릿속에 두셔도 보안 뉴스나 서비스 설명을 읽을 때 훨씬 정확하게 판단하실 수 있습니다.

잘못된 내용이나 보완할 점을 발견하셨다면 소개·문의의 이메일로 알려 주세요. 확인 후 글을 고치고 수정일을 갱신합니다.

함께 읽으면 좋은 글

다음 글: 대칭키 암호와 공개키 암호, 무엇이 다를까 → 번역기 열기