(Android/안드로이드) Base64 인코딩/디코딩 완전 정리
✨ 개요
- Base64는 바이너리 데이터를 텍스트(ASCII) 형태로 안전하게 전달하기 위한 인코딩 방식입니다.
- 이미지(byte array), 파일, 암호 키, 토큰 등 “바이너리”를 HTTP/JSON/QueryString 같은 텍스트 채널로 보내야 할 때 자주 사용합니다.
1. 요약
- Base64는 암호화가 아니라 인코딩이다(보안 목적 X)
- 크기는 대략 약 33% 증가(3바이트 → 4문자)
- Android에서는 android.util.Base64의 플래그를 잘 선택해야 함
- JSON/헤더/토큰: 보통 NO_WRAP
- URL/Query: URL_SAFE + NO_WRAP
- Padding(=)이 싫으면 NO_PADDING (상대가 허용하는지 확인)
2. Base64란? (왜 쓰나)
사용 목적
- 바이너리 데이터를 텍스트로 바꿔 전송/저장하기
- 이메일 MIME, HTTP 본문/헤더, JSON, 로그, 설정값 등에 활용
주의: 암호화가 아니다
- Base64는 누구나 쉽게 원복 가능한 인코딩입니다.
- 민감 정보는 Base64로 “숨긴다”가 아니라, TLS + 암호화로 보호해야 합니다.
3. Android Base64 API (android.util.Base64)
Android에서는 주로 아래 클래스를 사용합니다.
import android.util.Base64
- Base64.encodeToString(bytes, flags)
- Base64.decode(string, flags)
- Base64.encode(bytes, flags) (ByteArray 반환)
4. Kotlin/Android: Base64 인코딩 예제
4.1 ByteArray → Base64 String
val bytes: ByteArray = "hello".toByteArray(Charsets.UTF_8)
val encoded: String = Base64.encodeToString(bytes, Base64.NO_WRAP)
4.2 Base64 String → ByteArray (디코딩)
val decodedBytes: ByteArray = Base64.decode(encoded, Base64.DEFAULT)
val decodedText = decodedBytes.toString(Charsets.UTF_8)
5. 옵션(flags) 정리
Android Base64는 두 번째 인자로 flags(옵션)를 받습니다.
Default- 기본 설정
- 줄바꿈(LF)이 들어갈 수 있음(긴 문자열에서)
- 일반적인 본문/파일용이면 괜찮지만, JSON/헤더에서는 종종 문제가 됩니다.
NO_WRAP(가장 많이 쓰는 주 옵션)- 줄바꿈을 하지 않음
- JWT, Authorization 헤더, JSON 필드 등에 매우 적합
- Base64.encodeToString(bytes, Base64.NO_WRAP)
NO_PADDING- 끝의 = 패딩 문자를 제거
- 상대 시스템이 패딩 없는 Base64를 받아줄 때만 사용
- Base64.encodeToString(bytes, Base64.NO_WRAP or Base64.NO_PADDING)
URL_SAFE- +와 / 대신 -와 _를 사용하여 URL/QueryString에 안전
- URL/딥링크/쿼리에 넣을 Base64면 거의 필수
- Base64.encodeToString(bytes, Base64.URL_SAFE or Base64.NO_WRAP)
CRLF- 줄바꿈을 LF(\n) 대신 CRLF(\r\n)로 처리
- 이메일/일부 프로토콜에서 쓰이지만 모바일 앱에서는 흔치 않음
NO_CLOSE- 스트림 기반 API에서 close 동작 제어 용도
- 일반적으로 encodeToString/decode만 쓸 땐 거의 사용하지 않음
6. 어떤 옵션을 언제 쓰는지
| 사용처 | 추천 flags | 이유 |
|---|---|---|
| JSON 필드/로컬 저장/로그 | NO_WRAP |
줄바꿈 금지 |
| HTTP Header (Authorization 등) | NO_WRAP |
헤더 줄바꿈은 위험 |
| URL/QueryString/딥링크 파라미터 | URL_SAFE or NO_WRAP |
URL 예약문자 회피 |
| “=” 패딩이 문제되는 시스템 | NO_PADDING + (URL_SAFE/NO_WRAP) |
상대가 허용할 때만 |
7. 자주 나오는 문제/주의사항
- 줄바꿈 때문에 서버에서 실패
- DEFAULT는 길이에 따라 줄바꿈이 들어갈 수 있어, JSON/헤더에서 문제가 됩니다.
- NO_WRAP 사용 권장
- URL에 넣었더니 + / 때문에 깨짐
- URL에서 +는 공백으로 해석되거나, /는 경로로 해석될 수 있습니다.
- URL_SAFE 사용
- 패딩(=)이 없어 디코딩 실패
- 상대가 표준 Base64만 받는다면 패딩이 필요합니다.
- NO_PADDING은 상대 호환성 확인 후 사용
- Base64는 크기가 커진다
- 대략 33% 정도 커지므로, 대형 파일을 Base64로 API에 싣는 것은 비효율적일 수 있습니다.
- 대용량은 업로드(멀티파트) 등 별도 전송 방식을 고려