简体   繁体   中英

Remove \r and \n from AES encrypted string

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?

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

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

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

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM