Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Base64 in Android

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on.

Base64 in Android

Avatar for Keishin Yokomaku

Keishin Yokomaku

August 27, 2025
Tweet

More Decks by Keishin Yokomaku

Other Decks in Technology

Transcript

  1. About me • Keishin Yokomaku - @KeithYokoma • GitHub /

    X / Stack Over fl ow • Drivemode, Inc. / Engineer
  2. Base64 • Binary to text encoding Base64.encode() Base64.decode() ByteArray[1, 34,

    -2, 0, 0, …] “EaFueSBoYW5kcy…” ByteArray[1, 34, -2, 0, 0, …] “EaFueSBoYW5kcy…”
  3. Base64 • Binary to text encoding • Split the original

    byte array into chunks with 6bits each • Map the 6 bits into 1 character ( fi ll 0 for missing bits) • Create new chunks with 4 characters each ( fi ll = for missing characters) • Concatenate the chunks into single string
  4. Base64 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001,

    11 01000001010000100100001101000100010001010100011001000111
  5. Base64 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001,

    110000 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 11 01000001010000100100001101000100010001010100011001000111
  6. Base64 Q, U, J, D, R, E, V, G, R,

    w 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 110000 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 11 01000001010000100100001101000100010001010100011001000111
  7. Base64 QUJD, REVG, Rw Q, U, J, D, R, E,

    V, G, R, w 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 110000 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 11 01000001010000100100001101000100010001010100011001000111
  8. Base64 QUJD, REVG, Rw== QUJD, REVG, Rw Q, U, J,

    D, R, E, V, G, R, w 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 110000 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 11 01000001010000100100001101000100010001010100011001000111
  9. Base64 QUJDREVGRw== QUJD, REVG, Rw Q, U, J, D, R,

    E, V, G, R, w 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 110000 010000, 010100, 001001, 000011, 010001, 000100, 010101, 000110, 010001, 11 01000001010000100100001101000100010001010100011001000111
  10. Base64 classes • 3 Base64s by default • java.util.Base64 •

    android.util.Base64 • kotlin.io.encoding.Base64
  11. Why

  12. Di ff erent RFCs for Base64 encoding • java.util.Base64 •

    RFC 4648 and RFC 2045 • android.util.Base64 • RFC 3548 and RFC 2045 • kotlin.io.encoding.Base64 • RFC 4648 and a few other RFCs
  13. They are not interchangeable • What happens if… • Write

    encoded string to a fi le with android.util.Base64 with DEFAULT fl ag • Then read the fi le to decode kotlin.io.encoding.Base64.Default 📱 📱 android.util.Base64 kotlin.io.encoding.Base64 send TW9iaWxlIERldiBKYXBhbg== “Mobile Dev Japan” ?
  14. They are not interchangeable • It will CRASH • android.util.Base64

    separates lines with 76 characters each, adds line separators including last line • kotlin.io.encoding.Base64.Default will reject the line separators 📱 📱 android.util.Base64 kotlin.io.encoding.Base64 send TW9iaWxlIERldiBKYXBhbg== “Mobile Dev Japan” 💥 “Mobile Dev Japan”
  15. They are not interchangeable • It will WORK if the

    other way around • kotlin.io.encoding.Base64.Default will not add line separators • android.util.Base64 doesn’t care if it contains more than 76 characters in the single line, as it ignores line separator 📱 📱 kotlin.io.encoding.Base64 android.util.Base64 send TW9iaWxlIERldiBKYXBhbg== “Mobile Dev Japan” “Mobile Dev Japan”
  16. Mitigation • Case: encode with android.util.Base64 • Use additional fl

    ags (NO_WRAP, CRLF) when encoding • This doesn’t guarantee that output from android.util.Base64 satisfy other RFCs that java.util.Base64 or kotlin.io.encoding.Base64 follow
  17. Wrap up • Consider not using android.util.Base64 as much as

    possible https://issuetracker.google.com/issues/141497577
  18. Wrap up • Use the same class on both ends

    📱 📱 kotlin.io.encoding.Base64 kotlin.io.encoding.Base64 send TW9iaWxlIERldiBKYXBhbg== “Mobile Dev Japan” “Mobile Dev Japan” 📱 📱 android.util.Base64 android.util.Base64 send TW9iaWxlIERldiBKYXBhbg== “Mobile Dev Japan” “Mobile Dev Japan”