【问题标题】:Remove \r and \n from AES encrypted string从 AES 加密字符串中删除 \r 和 \n
【发布时间】:2014-03-18 03:42:22
【问题描述】:

我正在使用 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 编码器选项来防止添加字符。

标签: java encryption aes newline carriage-return


【解决方案1】:

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

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

点击这里:source

点击这里:Main source

【讨论】:

  • Dheivame.. enna kaapathita dheivame.
【解决方案2】:

实际上,我使用 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

【讨论】:

    【解决方案3】:

    base64 编码标准似乎要求至少每 75 个字符有一个换行符。我的猜测是 base64 编码功能会自动添加它,您没有做错任何事情,将其保留或删除都可以。根据下面的链接,base64解码函数应该忽略换行符,所以是否删除它取决于你......

    其他遇到此问题的人请参阅此处,并引用 base64 标准:http://lists.w3.org/Archives/Public/w3c-ietf-xmldsig/2001AprJun/0183.html

    【讨论】:

    • BUT 我要强调的是,更改加密字符串中的值肯定会在某些时候造成麻烦。
    • 同意!搞乱加密字符串可能不是一个好主意!
    • 更改空白不应导致问题,除非另一端的 Base64 解码器坚持存在(这不太可能)。
    • 非常感谢您的帮助..我使用的是 apache commons-codec-1.4.0.jar ..将其更改为更高版本可以解决问题。实际上,encodeBase64String 方法的行为已经从多行分块(commons-codec-1.4)更改为单行非分块(commons-codec-1.5)。请点击此链接commons.apache.org/proper/commons-codec/apidocs/org/apache/…
    • trim() 它不会造成问题
    【解决方案4】:

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

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

    【讨论】:

      【解决方案5】:

      这是在编码字符串末尾添加 \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)
      

      【讨论】:

        猜你喜欢
        • 2016-06-20
        • 2019-10-24
        • 2011-11-11
        • 2021-12-06
        • 1970-01-01
        • 2022-01-24
        • 2016-01-05
        相关资源
        最近更新 更多