web-dev-qa-db-fra.com

Base64: exception Java.lang.IllegalArgument: caractère illégal

J'essaie d'envoyer un courrier électronique de confirmation après l'enregistrement de l'utilisateur. J'utilise la bibliothèque JavaMail à cet effet et la classe utilitaire Java 8 Base64.

J'encode les courriels des utilisateurs de la manière suivante:

byte[] encodedEmail = Base64.getUrlEncoder().encode(user.getEmail().getBytes(StandardCharsets.UTF_8));
Multipart multipart = new MimeMultipart();
InternetHeaders headers = new InternetHeaders();
headers.addHeader("Content-type", "text/html; charset=UTF-8");
String confirmLink = "Complete your registration by clicking on following"+ "\n<a href='" + confirmationURL + encodedEmail + "'>link</a>";
MimeBodyPart link = new MimeBodyPart(headers,
confirmLink.getBytes("UTF-8"));
multipart.addBodyPart(link);

confirmationURL est:

private final static String confirmationURL = "http://localhost:8080/project/controller?command=confirmRegistration&ID=";

Et ensuite décoder cela dans ConfirmRegistrationCommand de la manière suivante:

    String encryptedEmail = request.getParameter("ID");

    String decodedEmail = new String(Base64.getUrlDecoder().decode(encryptedEmail), StandardCharsets.UTF_8);

    RepositoryFactory repositoryFactory = RepositoryFactory
            .getFactoryByName(FactoryType.MYSQL_REPOSITORY_FACTORY);
    UserRepository userRepository = repositoryFactory.getUserRepository();
    User user = userRepository.find(decodedEmail);

    if (user.getEmail().equals(decodedEmail)) {
        user.setActiveStatus(true);
        return Path.WELCOME_PAGE;
    } else {
        return Path.ERROR_PAGE;
    }

Et quand j'essaye de décoder:

http://localhost:8080/project/controller?command=confirmRegistration&ID=[B@6499375d

Je reçois Java.lang.IllegalArgumentException: Illegal base64 character 5b.

J'ai essayé d'utiliser de base Encode/Decoder (pas les URL) sans succès.

RESOLU:

Le problème était le suivant - dans la ligne:

 String confirmLink = "Complete your registration by clicking on following"+ "\n<a href='" + confirmationURL + encodedEmail + "'>link</a>";

J'appelle toString sur un tableau d'octets, je devrais donc procéder comme suit:

String encodedEmail = new String(Base64.getEncoder().encode(
                user.getEmail().getBytes(StandardCharsets.UTF_8)));

Merci à Jon Skeet et ByteHamster .

12
marknorkin

Votre texte codé est [B@6499375d. Ce n'est pas Base64, quelque chose a mal tourné pendant que encoding . Ce code de décodage a l'air bien.

Utilisez ce code pour convertir l'octet [] en une chaîne avant de l'ajouter à l'URL:

String encodedEmailString = new String(encodedEmail, "UTF-8");
// ...
String confirmLink = "Complete your registration by clicking on following"
    + "\n<a href='" + confirmationURL + encodedEmailString + "'>link</a>";
13
ByteHamster

J'ai rencontré cette erreur depuis que mon image codée a démarré avec data:image/png;base64,iVBORw0....

Cette réponse m'a conduit à la solution:

String partSeparator = ",";
if (data.contains(partSeparator) {
  String encodedImg = data.split(partSeparator)[1];
  byte[] decodedImg = Base64.getDecoder().decode(encodedImg.getBytes(StandardCharsets.UTF_8));
  Path destinationFile = Paths.get("/path/to/imageDir", "myImage.jpg");
  Files.write(destinationFile, decodedImg);
}
8
Matthias Braun

Utilisez simplement le code ci-dessous pour résoudre ceci:

JsonObject obj = Json.createReader(new ByteArrayInputStream(Base64.getDecoder().decode(accessToken.split("\\.")[1].
                        replace('-', '+').replace('_', '/')))).readObject();

Dans le code ci-dessus, replace('-', '+').replace('_', '/') a effectué le travail. Pour plus de détails, voir https://jwt.io/js/jwt.js . J'ai compris le problème de la partie du code obtenue à partir de ce lien:

function url_base64_decode(str) {
  var output = str.replace(/-/g, '+').replace(/_/g, '/');
  switch (output.length % 4) {
    case 0:
      break;
    case 2:
      output += '==';
      break;
    case 3:
      output += '=';
      break;
    default:
      throw 'Illegal base64url string!';
  }
  var result = window.atob(output); //polifyll https://github.com/davidchambers/Base64.js
  try{
    return decodeURIComponent(escape(result));
  } catch (err) {
    return result;
  }
}
2
Esakkiappan .E

La méthode Base64.Encoder.encodeToString utilise automatiquement le jeu de caractères ISO-8859-1.

Pour un utilitaire de chiffrement que j'écris, j'ai pris la chaîne de saisie de texte chiffré et Base64 l'a codée pour la transmission, puis inversé le processus. Parties pertinentes indiquées ci-dessous. REMARQUE: Ma propriété file.encoding est définie sur ISO-8859-1 lors de l'appel de la machine virtuelle Java, ce qui peut également avoir un relèvement.

static String getBase64EncodedCipherText(String cipherText) {
    byte[] cText = cipherText.getBytes();
    // return an ISO-8859-1 encoded String
    return Base64.getEncoder().encodeToString(cText);
}

static String getBase64DecodedCipherText(String encodedCipherText) throws IOException {
    return new String((Base64.getDecoder().decode(encodedCipherText)));
}

public static void main(String[] args) {
    try {
        String cText = getRawCipherText(null, "Hello World of Encryption...");

        System.out.println("Text to encrypt/encode: Hello World of Encryption...");
        // This output is a simple sanity check to display that the text
        // has indeed been converted to a cipher text which 
        // is unreadable by all but the most intelligent of programmers.
        // It is absolutely inhuman of me to do such a thing, but I am a
        // rebel and cannot be trusted in any way.  Please look away.
        System.out.println("RAW CIPHER TEXT: " + cText);
        cText = getBase64EncodedCipherText(cText);
        System.out.println("BASE64 ENCODED: " + cText);
        // There he goes again!!
        System.out.println("BASE64 DECODED:  " + getBase64DecodedCipherText(cText));
        System.out.println("DECODED CIPHER TEXT: " + decodeRawCipherText(null, getBase64DecodedCipherText(cText)));
    } catch (Exception e) {
        e.printStackTrace();
    }

}

La sortie ressemble à:

Text to encrypt/encode: Hello World of Encryption...
RAW CIPHER TEXT: q$;�C�l��<8��U���X[7l
BASE64 ENCODED: HnEPJDuhQ+qDbInUCzw4gx0VDqtVwef+WFs3bA==
BASE64 DECODED:  q$;�C�l��<8��U���X[7l``
DECODED CIPHER TEXT: Hello World of Encryption...
1
guitarpicva

J'ai eu cette erreur pour mon esclave Linux Jenkins. Je l'ai corrigé en remplaçant le nœud "Stratégie de vérification du fichier d'hôtes connus" par "Stratégie de vérification non vérifiée".

0
twasbrillig