pxb1988/dex2jar · error · IllegalArgumentException

bad base-64

Error message

bad base-64

What it means

This IllegalArgumentException is thrown by the Android-style Base64 decoder in d2j signapk when decoder.process() detects that the input bytes are not valid base-64 (illegal characters, bad padding, or truncated final quantum). The library uses this decoder when handling signed JARs, and it fails fast instead of returning partial data.

Solutions

  1. Inspect and sanitize the input: strip non-base-64 characters (headers like '-----BEGIN...', newlines) before decoding.
  2. Use the flag Base64.DEFAULT (or add Base64.URL_SAFE / NO_PADDING / NO_CLOSE as appropriate) to match how the data was originally encoded.
  3. Verify the input length: raw base-64 without padding must be handled with NO_PADDING, or re-pad the input to a multiple of 4.
  4. Confirm the byte source is correct — re-extract the data from the APK/JAR rather than decoding a truncated or hand-edited copy.

Example fix

// before
byte[] data = Base64.decode(cert.getText().trim().getBytes(), 0);
// after
String b64 = cert.getText().replaceAll("-----[A-Z ]+-----|\\s", "");
byte[] data = Base64.decode(b64.getBytes(), Base64.DEFAULT);
Defensive patterns

Strategy: validation

Validate before calling

// validate before decoding
String b64 = raw.replaceAll("-----[A-Z ]+-----|\\s", "");
if (!b64.matches("[A-Za-z0-9+/]*={0,2}") || b64.length() % 4 != 0) {
    throw new IllegalArgumentException("input is not valid base-64");
}
byte[] data = Base64.decode(b64.getBytes(), Base64.DEFAULT);

Try / catch

try {
    byte[] data = Base64.decode(input, Base64.DEFAULT);
} catch (IllegalArgumentException e) {
    // fall back to lenient decode or surface a clear 'corrupted signature' message
}

Prevention

When it happens

Trigger: Calling Base64.decode(byte[] input, int offset, int len, int flags) (or the delegating decode overloads) with bytes containing characters outside the base-64 alphabet, an '=' in a non-final position, or a length that is not a valid multiple of 4 (ignoring whitespace).

Common situations: Decoding a signature block or manifest digest that was corrupted, copied with surrounding text, line-wrapped with characters the decoder does not treat as whitespace, or is actually hex/plain text rather than base-64.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of pxb1988/dex2jar@b5bda4fb49 (2026-09-08). Data as JSON: /api/errors/be2cb435cb49b05f. Report an issue: GitHub.

Appendix: source

Thrown at dex-tools/src/main/java/com/googlecode/d2j/signapk/Base64.java:159

     * <p>The padding '=' characters at the end are considered optional, but
     * if any are present, there must be the correct number of them.
     *
     * @param input  the data to decode
     * @param offset the position within the input array at which to start
     * @param len    the number of bytes of input to decode
     * @param flags  controls certain features of the decoded output.
     *               Pass {@code DEFAULT} to decode standard Base64.
     *
     * @throws IllegalArgumentException if the input contains
     * incorrect padding
     */
    public static byte[] decode(byte[] input, int offset, int len, int flags) {
        // Allocate space for the most data the input could represent.
        // (It could contain less if it contains whitespace, etc.)
        Decoder decoder = new Decoder(flags, new byte[len*3/4]);

        if (!decoder.process(input, offset, len, true)) {
            throw new IllegalArgumentException("bad base-64");
        }

        // Maybe we got lucky and allocated exactly enough output space.
        if (decoder.op == decoder.output.length) {
            return decoder.output;
        }

        // Need to shorten the array, so allocate a new one of the
        // right size and copy.
        byte[] temp = new byte[decoder.op];
        System.arraycopy(decoder.output, 0, temp, 0, decoder.op);
        return temp;
    }

    /* package */ static class Decoder extends Coder {
        /**
         * Lookup table for turning bytes into their position in the
         * Base64 alphabet.

View on GitHub (pinned to b5bda4fb49)