Перейти к содержимому
ecdsa.com
Java (JDK)Java

Сообщение об ошибке

java.lang.IllegalArgumentException: Illegal base64 character 2d

Также выводится как

  • java.lang.IllegalArgumentException: Illegal base64 character a
  • java.lang.IllegalArgumentException: Illegal base64 character d
  • java.lang.IllegalArgumentException: Illegal base64 character 5f
  • java.lang.IllegalArgumentException: Illegal base64 character 20

Шестнадцатеричное значение указывает на недопустимый символ: `2d` — «-», `5f` — «_», `a` — LF, `d` — CR, `20` — пробел.

Java (JDK) — java.util.Base64.Decoder.decode

Что это означает

`Base64.getDecoder()` — строгий декодер по RFC 4648: он принимает только `A–Z a–z 0–9 + /` и дополнение `=` и останавливается на первом же символе не из этого набора. Шестнадцатеричное число — код этого символа: `2d` — это `-` (дефисы из `-----BEGIN …-----` или алфавит base64url), `a` — перевод строки, `d` — возврат каретки, `20` — пробел, `5f` — подчёркивание. С самими данными обычно всё в порядке: они просто в другой текстовой обёртке, чем ожидает декодер.

Почему это происходит

Как исправить

  1. 1.

    Уберите обрамление и используйте декодер MIME

    `Base64.getMimeDecoder()` пропускает разделители строк — именно это и нужно для тела PEM.

    java
    String body = pem.replaceAll("-----(BEGIN|END) [A-Z ]+-----", "");
    byte[] der = Base64.getMimeDecoder().decode(body); // ignores line separators and other non-alphabet characters
  2. 2.

    Используйте для данных JOSE декодер URL

    Всё содержимое JWT и JWK закодировано в base64url; декодер URL к тому же принимает данные без дополнения.

    java
    // JWT segments and JWK fields ("x", "y", "n", "e") use base64url without padding.
    byte[] header = Base64.getUrlDecoder().decode(jwt.split("\\.")[0]);
    byte[] x = Base64.getUrlDecoder().decode(jwk.get("x"));

Связанные ошибки

Открыть всю базу ошибок подписей