相同的代码在main中和servlet中结果不同 Charset.defaultCharset
在进行加解密的时候,同样的代码,在main中可以正常解密,在servlet中却是乱码。。。
可以排除代码和加密算法问题,应该是编码有问题
String de = EncryptUtil.decryptAes("5lbDEpBwfXhKWqvrMFyD6A==", "3gsuK6rfsWT9rTUd");
//上面这句在servlet中执行结果为乱码
最后发现问题:太粗心了,在返回解密后的字符串时没有指定编码格式,结果Charset.defaultCharset().name()==GBK,就乱了
public static String decryptAes(String data,String key) throws Exception{ Key k = toKey(key); Cipher cipher = Cipher.getInstance("AES/CBC/ISO10126Padding"); IvParameterSpec iv = new IvParameterSpec(key.getBytes()); cipher.init(Cipher.DECRYPT_MODE, k,iv); return new String(cipher.doFinal(decryptBASE64(data)),"utf-8");//默认GBK,应指定utf-8 }
当程序在需要指定编码的地方没有显示指定编码格式,那么他会实用Charset.defaultCharset().name()作为默认编码格式。
而这个编码格式可以自行设置myeclipsexia:window-->preferences-->Installed JRES-->jkd_1.7.0_21-->Default VM Arguments-->-Dfile.encoding=UTF-8,如果没有进行设置,那么这个默认编码会通过底层操作系统来进行设置,个人感觉应该是根据系统的时区和地区
查看源码如下:
/** * Returns the default charset of this Java virtual machine. * * <p> The default charset is determined during virtual-machine startup and * typically depends upon the locale and charset of the underlying * operating system. * * @return A charset object for the default charset * * @since 1.5 */ public static Charset defaultCharset() { if (defaultCharset == null) { synchronized (Charset.class) { String csn = AccessController.doPrivileged( new GetPropertyAction("file.encoding")); Charset cs = lookup(csn); if (cs != null) defaultCharset = cs; else defaultCharset = forName("UTF-8"); } } return defaultCharset; } private static Charset lookup(String charsetName) { if (charsetName == null) throw new IllegalArgumentException("Null charset name"); Object[] a; if ((a = cache1) != null && charsetName.equals(a[0])) return (Charset)a[1]; // We expect most programs to use one Charset repeatedly. // We convey a hint to this effect to the VM by putting the // level 1 cache miss code in a separate method. return lookup2(charsetName); }
这个cache不晓得是干啥的,还有,main和servlet中这defaultCharset有时会不通?