从AES加密字符串中删除\r和\n

7

我正在使用AES加密字符串,但加密后的字符串末尾包含\n\r

 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;
  }
}

输出

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

事实上,加密字符串是 TUDUORnWtsZFJAhBw1fYMF9CFExb/tSsLeDx++cpupI=/r/n。 我是否需要显式替换加密字符串中的\r\n,或者我在上面的代码中做错了什么?


Base64字符串中的空格会被忽略,这并没有问题。虽然可能有一些Base64编码器选项可以防止添加这些字符。 - Hot Licks
5个回答

16

添加Base64.encodeBase64String(hashPassword,Base64.NO_WRAP)会去除 \n。

默认情况下使用Base64.DEFAULT,会添加换行符。

点击这里:来源

点击这里:主要来源


6

1
似乎 base64 编码标准要求每 75 个字符至少有一个换行符。我的猜测是,base64 编码函数会自动添加这个,你没有做错任何事情,保留或删除都可以。根据下面的链接,base64 解码函数应该忽略换行符,因此是否删除取决于你...请参见这里的其他人遇到的问题和来自 base64 标准的引用:http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001AprJun/0183.html

2
但是我要强调的是,在加密字符串中更改值必定会在某个时候引起麻烦。 - christopher
同意!胡乱处理加密字符串可能不是一个好主意! - user1578653
1
更改空格不应该成为问题,除非另一端的Base64解码器坚持它必须存在(这是不太可能的)。 - Hot Licks
非常感谢您的帮助。我之前使用的是apache commons-codec-1.4.0.jar,将其更改为更高版本解决了问题。实际上,encodeBase64String方法的行为已从多行分块(commons-codec-1.4)更改为单行非分块(commons-codec-1.5)。请参考此链接http://commons.apache.org/proper/commons-codec/apidocs/org/apache/commons/codec/binary/Base64.html。 - user3244519
trim() 不会导致问题 - Emre Kilinc Arslan

0
这是添加 \n 到编码字符串末尾的代码块。
        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)
            )
        }

以下是代码,它可以正常工作!

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)

0

只需对编码字符串执行encryptedString = encryptedString.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "")

当您尝试将其解码回字节时,它能正常工作。我使用随机生成的字节数组进行了多次测试。显然,解码过程会忽略换行符,无论它们是否存在。我使用了com.sun.org.apache.xml.internal.security.utils.Base64进行了“确认有效”的测试。其他编码器没有经过测试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接