7

I am encrypting a string using AES but the encrypted string contains \n and \r at the end.

 public class AESImpl {

  private static String decryptedString;

  private static String encryptedString;

  public static void main(String[] args) throws NoSuchAlgorithmException, IOException,  ClassNotFoundException {

    String strToEncrypt = "This text has to be encrypted";
    SecretKey secretKey = generateSecretKey();
    String encryptStr = encrypt(strToEncrypt, secretKey);
    System.out.println("Encrypted String : " + encryptStr + "It should not come in new line");
    String decryptStr = decrypt(encryptStr, secretKey);
    System.out.println("Decrypted String : " + decryptStr);
  }

  private static SecretKey generateSecretKey() throws NoSuchAlgorithmException, IOException {
    KeyGenerator kg = KeyGenerator.getInstance("AES");
    kg.init(128);
    SecretKey sk = kg.generateKey();
    String secretKey = String.valueOf(Hex.encodeHex(sk.getEncoded()));
    System.out.println("Secret key is " + secretKey);
    return sk;
  }

  public static String encrypt(String strToEncrypt, SecretKey secretKey) {
    try {
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
      cipher.init(Cipher.ENCRYPT_MODE, secretKey);
      encryptedString = new String(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes())));
    } catch (Exception e) {
      System.out.println("Error while encrypting: " + e.toString());
    }

    return encryptedString;
  }

  public static String decrypt(String strToDecrypt, SecretKey secretKey) {
    try {
      Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
      cipher.init(Cipher.DECRYPT_MODE, secretKey);
      decryptedString = new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt)));
    } catch (Exception e) {
      System.out.println("Error while decrypting: " + e.toString());
    }

    return decryptedString;
  }
}

Output

Secret key is 2df36561b09370637d35b4a310617e60
Encrypted String : TUDUORnWtsZFJAhBw1fYMF9CFExb/tSsLeDx++cpupI=
It should not come in new line
Decrypted String : This text has to be encrypted

Actually, the encrypted string is TUDUORnWtsZFJAhBw1fYMF9CFExb/tSsLeDx++cpupI=/r/n. Do I need to explicitly replace the \r and \n from encrypted string or I have done something wrong in the above code?

MilanPanchal
  • 2,943
  • 1
  • 19
  • 37
user3244519
  • 661
  • 5
  • 18
  • 36
  • White space in a Base64 string is ignored. There is nothing wrong. Though there may be a Base64 encoder option to prevent the adding of the characters. – Hot Licks Feb 18 '14 at 12:20

5 Answers5

16

Adding Base64.encodeBase64String(hashPassword,Base64.NO_WRAP) removes the \n.

By default it uses Base64.DEFAULT which adds newline.

click here: source

click here: Main source

Community
  • 1
  • 1
pallavi
  • 432
  • 3
  • 14
6

Actually,I was using apache commons-codec-1.4.0.jar to encode the string. Changing it to higher version solves the issue. The behaviour of encodeBase64String method has been changed from multi-line chunking (commons-codec-1.4) to single-line non-chunking (commons-codec-1.5).

Please follow the link for more details. http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64.html

user3244519
  • 661
  • 5
  • 18
  • 36
1

It seems like the base64 encoding standard requires that there is a line break at least every 75 characters. My guess is that the base64 encoding function is adding this automatically, you haven't done anything wrong, and that it's fine to leave it in or remove it. According to the link below, base64 decoding functions should ignore line breaks, so whether you remove it or not is up to you...

See here for someone else who's run into this problem, and a quote from the base64 standard: http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001AprJun/0183.html

user1578653
  • 4,888
  • 16
  • 46
  • 74
  • 2
    ***BUT*** I would stress that changing values in an encrypted string is bound to cause trouble at some point or another. – christopher Feb 18 '14 at 12:03
  • Agreed! Messing about with encrypted strings is probably not a good idea! – user1578653 Feb 18 '14 at 12:04
  • 1
    Changing the whitespace should not cause a problem unless the Base64 decoder on the other end insists it be there (which is unlikely). – Hot Licks Feb 18 '14 at 12:22
  • Thanks a lot for your help..I was using apache commons-codec-1.4.0.jar..changing it to higher version solves the issue. Actually, the behaviour of encodeBase64String method has been changed from multi-line chunking (commons-codec-1.4) to single-line non-chunking (commons-codec-1.5).Please follow this link http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64.html – user3244519 Feb 18 '14 at 12:22
  • trim() it it will not make a problem – Emre Kilinc Arslan Mar 24 '21 at 16:37
0

Simply perform encryptedString = encryptedString.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "") on the encoded string.

It works fine when you try do decode it back to bytes. I did test it several times with random generated byte arrays. Obviously decoding process just ignores the newlines either they are present or not. I tested this "confirmed working" by using com.sun.org.apache.xml.internal.security.utils.Base64 Other encoders not tested.

shehzad lakhani
  • 495
  • 5
  • 14
0

This is the code block which adds \n at the end ofthe encoded string

        keyBytes = secret_key.substring(0, 32).toByteArray(charset("UTF8"))
        val skey = SecretKeySpec(keyBytes, "AES")
        val input = strToEncrypt.toByteArray(charset("UTF8"))

        synchronized(Cipher::class.java) {
            val cipher = Cipher.getInstance("AES/ECB/PKCS5Padding")
            cipher.init(Cipher.ENCRYPT_MODE, skey)

            val cipherText = ByteArray(cipher.getOutputSize(input.size))
            var ctLength = cipher.update(
                input, 0, input.size,
                cipherText, 0
            )
            ctLength += cipher.doFinal(cipherText, ctLength)
            return String(
                android.util.Base64.encode(cipherText, 1)
            )
        }

and THIS IS THE CODE BELOW WORKS FINE !!

val algorithm = "AES"
            val keyValue = secret_key.substring(0, 32).toByteArray(charset("UTF8"))
            val key: Key = SecretKeySpec(keyValue, algorithm)
            val c: Cipher = Cipher.getInstance(algorithm, "BC")
            c.init(Cipher.ENCRYPT_MODE, key);
            val encValue: ByteArray =
                c.doFinal(
                    strToEncrypt.toByteArray()
                )
            return Base64.getEncoder().encodeToString(encValue)
Emre Kilinc Arslan
  • 2,019
  • 2
  • 16
  • 12