Ошибка при декодировании байтового массива в base64, который содержит символы, такие как '-' и '_' - PullRequest
0 голосов
/ 03 октября 2018

Я пытаюсь с помощью base64 декодировать байтовый массив, и все работает нормально, пока мой байтовый массив не содержит никаких символов, таких как '-'or' _ '.Но всякий раз, когда байтовый массив содержит '-', я получаю исключение как

java.lang.IllegalArgumentException: Illegal base64 character 2d
    at java.util.Base64$Decoder.decode0(Base64.java:714)
    at java.util.Base64$Decoder.decode(Base64.java:526)

, а когда байтовый массив содержит'_ ', исключение составляет

java.lang.IllegalArgumentException: Illegal base64 character 5f
    at java.util.Base64$Decoder.decode0(Base64.java:714)
    at java.util.Base64$Decoder.decode(Base64.java:526)

, т.е. разница кодапосле символа от 2d до 5f.Каковы эти коды.И как я могу декодировать любое значение независимо от этих символов в моем коде?

Вот мой фрагмент кода:

import java.util.Properties;
import java.util.Base64;
import java.io.*;
...

public class BasicSample {

    public static void main(String[] args) {
      byte[] encoded = res.getBytes("s_id");
      System.out.printf("\nInside Byte %s\n",new String(encoded) );
      try {
        byte[] decoded = Base64.getDecoder().decode(encoded);

        System.out.printf("\nDecoded Byte %s\n",new String(decoded, "UTF-8") );
      } catch(Exception e) {
        e.printStackTrace();
      }
   }

}

Ответы [ 2 ]

0 голосов
/ 15 августа 2019

Решение

Заменить '-' на '+' и '_' на '/', как показано в строке ниже

byte[] decoded = Base64.getDecoder().decode(encoded.replace('-', '+').replace('_', '/'));

Обоснование

Есть Base64 кодировка и есть Base64url кодировка.Они точно такие же, за исключением двух замен символов, указанных выше.

Посмотрите на Таблицу 1 и Таблицу 2 в RFC 4648 :

                Table 1: The Base 64 Alphabet

 Value Encoding  Value Encoding  Value Encoding  Value Encoding
     0 A            17 R            34 i            51 z
     1 B            18 S            35 j            52 0
     2 C            19 T            36 k            53 1
     3 D            20 U            37 l            54 2
     4 E            21 V            38 m            55 3
     5 F            22 W            39 n            56 4
     6 G            23 X            40 o            57 5
     7 H            24 Y            41 p            58 6
     8 I            25 Z            42 q            59 7
     9 J            26 a            43 r            60 8
    10 K            27 b            44 s            61 9
    11 L            28 c            45 t            62 +
    12 M            29 d            46 u            63 /
    13 N            30 e            47 v
    14 O            31 f            48 w         (pad) =
    15 P            32 g            49 x
    16 Q            33 h            50 y

[...]

                Table 2: The "URL and Filename safe" Base 64 Alphabet

 Value Encoding  Value Encoding  Value Encoding  Value Encoding
     0 A            17 R            34 i            51 z
     1 B            18 S            35 j            52 0
     2 C            19 T            36 k            53 1
     3 D            20 U            37 l            54 2
     4 E            21 V            38 m            55 3
     5 F            22 W            39 n            56 4
     6 G            23 X            40 o            57 5
     7 H            24 Y            41 p            58 6
     8 I            25 Z            42 q            59 7
     9 J            26 a            43 r            60 8
    10 K            27 b            44 s            61 9
    11 L            28 c            45 t            62 - (minus)
    12 M            29 d            46 u            63 _
    13 N            30 e            47 v           (underline)
    14 O            31 f            48 w
    15 P            32 g            49 x
    16 Q            33 h            50 y         (pad) =

Вот еще одна цитата из RFC:

Эта кодировкаможет упоминаться как "base64url".Это кодирование не должно рассматриваться как кодирование «base64» и не должно упоминаться как только «base64».Если не указано иное, «base64» относится к базе 64 в предыдущем разделе.Эта кодировка технически идентична предыдущей, за исключением букв алфавита 62: 63 и 63, как указано в таблице 2.

0 голосов
/ 03 октября 2018

Согласно RFC 2045 , Таблица 1: Алфавит Base64 ни -, ни _ не является частью алфавита.Только символы, присутствующие в алфавите, используются декодером Base64, вы не можете просто декодировать произвольные символы.

                Table 1: The Base64 Alphabet

 Value Encoding  Value Encoding  Value Encoding  Value Encoding
     0 A            17 R            34 i            51 z
     1 B            18 S            35 j            52 0
     2 C            19 T            36 k            53 1
     3 D            20 U            37 l            54 2
     4 E            21 V            38 m            55 3
     5 F            22 W            39 n            56 4
     6 G            23 X            40 o            57 5
     7 H            24 Y            41 p            58 6
     8 I            25 Z            42 q            59 7
     9 J            26 a            43 r            60 8
    10 K            27 b            44 s            61 9
    11 L            28 c            45 t            62 +
    12 M            29 d            46 u            63 /
    13 N            30 e            47 v
    14 O            31 f            48 w         (pad) =
    15 P            32 g            49 x
    16 Q            33 h            50 y

Как отметил Роланд Иллиг, вы можете иметь дело с URL-дружественным вариантом Base 64, где_ заменяет + и - заменяет /.В этом случае может быть достаточно отменить изменение перед декодированием:

String raw = new String(res.getBytes("s_id"));
String encoded = raw.replace("_", "+").replace("-", "/");
String decoded = Base64.getDecoder().decode(encoded);

Однако невозможно сказать, как на самом деле кодируются данные, не видя кодировку на стороне сервера.

...