解密具有特殊字符的字符串时出现 ArrayIndexOutOfBoundsException

ArrayIndexOutOfBoundsException when decrypting String with special character

使用 com.googlecode.gwt.crypto.client.TripleDesCipher#decrypt 解密字符串时抛出以下异常:

java.lang.ArrayIndexOutOfBoundsException: -59 
at com.googlecode.gwt.crypto.bouncycastle.util.encoders.HexEncoder.decode(HexEncoder.java:106) 
at com.googlecode.gwt.crypto.bouncycastle.util.encoders.Hex.decode(Hex.java:86)
at com.googlecode.gwt.crypto.client.TripleDesCipher.decrypt(TripleDesCipher.java:51)

传递给方法的字符串包含特殊字符。

你们有没有遇到过这样的错误?


传递给 decrypt 方法的字符串包含特殊字符 Ţ。它以 UTF-8 编码,但以某种方式被 TripleDesCipher 解析为 ISO-8859-1.

Java 自身的编码使用 UTF-16:大多数字符将使用 16 位,但也有一些例外。当一个字符不能用 UTF-16 编码时,它将使用 hi-surrogate (1 char) 和 low-surrogate (1 char) 进行编码,所以取 2 native Java char space.

你的字符表示是:

Ţ:带变音符号的拉丁文大写字母 T (U+0162):feff0162

java 表示将是 2 java 本机字符(0xfeff 和 0x0162)。 您可以通过测试一个字符是否为高代理项来检测此行为(在这种情况下,它后面必须紧跟一个低代理项)。

有关 javadoc 的更多信息:

http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isHighSurrogate%28char%29

通常在 Character header 文档中:

http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html

编辑

忘记之前的回复,它不应该与数据表示相关联。看来你想要 "decrypt" 的任何字符串都必须先加密为十六进制。因此,这排除了 Ţ 作为加密数据中的潜在值。在将其提供给 TripleDesCipher.decrypt 方法之前,您的输入应该已经是错误的。

正如答案中已经提到的,问题是我们读取了一个 UTF-8 字符串,因为它是 ISO-8859-1并将其传递给 decrypt 方法。

错误的编码是由于 multipart/form-data request