AES加密中文乱码

  前几天,使用AES加密,遇到一奇怪问题,用AES加密,解密后在windows下正常,在Linux中文确会加密成问号,当时才用的是AES/CBC/NoPadding模式,并且进行了base64加解密。

        通过多种尝试,均不知道为何。最后确定在AES/CBC/PKCS5Padding模式下和AES/ECB/PKCS5Padding模式下不会出现中文乱码的情况,同时因为ios只有AES/CBC/PKCS7Padding和AES/ECB/PKCS5Padding,在PHP中为zeropadding,所以采用了AES/ECB/PKCS5Padding模式,这样可以解决乱码问题,而且可以在oc,java,php三种语言中通用。但是因为php为zeropadding,我们在设置偏移量时需要把偏移量设置为16个0.来兼容各个版本语言。


下面是在网上找到的java版源码:

public class AES1 {
	// /** 算法/模式/填充 **/
	 private static final String CipherMode ="AES/CBC/PKCS5Padding";

	 // /** 创建密钥 **/
	 private static SecretKeySpec createKey(String key) {
	 byte[] data = null;
	 if (key == null) {
	 key ="";
	}
	 StringBuffer sb = new StringBuffer(16);
	sb.append(key);
	 while (sb.length() < 16) {
	sb.append("0");
	}
	 if (sb.length() > 16) {
	sb.setLength(16);
	}

	 try {
	 data = sb.toString().getBytes("UTF-8");
	 } catch (UnsupportedEncodingException e) {
	e.printStackTrace();
	}
	 return new SecretKeySpec(data,"AES");
	}

	 private static IvParameterSpec createIV(String password) {
	 byte[] data = null;
	 if (password == null) {
	 password ="";
	}
	 StringBuffer sb = new StringBuffer(16);
	sb.append(password);
	 while (sb.length() < 16) {
	sb.append("0");
	}
	 if (sb.length() > 16) {
	sb.setLength(16);
	}

	 try {
	 data = sb.toString().getBytes("UTF-8");
	 } catch (UnsupportedEncodingException e) {
	e.printStackTrace();
	}
	 return new IvParameterSpec(data);
	}

	 // /** 加密字节数据 **/
	 public static byte[] encrypt(byte[] content, String password, String iv) {
	 try {
	 SecretKeySpec key = createKey(password);
	 Cipher cipher = Cipher.getInstance(CipherMode);
	 cipher.init(Cipher.ENCRYPT_MODE, key, createIV(iv));
	 byte[] result = cipher.doFinal(content);
	 return result;
	 } catch (Exception e) {
	e.printStackTrace();
	}
	 return null;
	}

	 // /** 加密(结果为16进制字符串) **/
	 public static String encrypt(String content, String password, String iv) {
	 byte[] data = null;
	 try {
	 data = content.getBytes("UTF-8");
	 } catch (Exception e) {
	e.printStackTrace();
	}
	 data = encrypt(data, password, iv);
	 String result = new Base64().encodeToString(data);
	 return result;
	}

	 // /** 解密字节数组 **/
	 public static byte[] decrypt(byte[] content, String password, String iv) {
	 try {
	 SecretKeySpec key = createKey(password);
	 Cipher cipher = Cipher.getInstance(CipherMode);
	 cipher.init(Cipher.DECRYPT_MODE, key, createIV(iv));
	 byte[] result = cipher.doFinal(content);
	 return result;
	 } catch (Exception e) {
	e.printStackTrace();
	}
	 return null;
	}

	 // /** 解密 **/
	 public static String decrypt(String content, String password, String iv) {
	 byte[] data = null;
	 try {
	 data =  new Base64().decode(content);//先用base64解密
	 } catch (Exception e) {
	e.printStackTrace();
	}
	 data = decrypt(data, password, iv);
	 if (data == null)
	 return null;
	 String result = null;
	 try {
	 result = new String(data,"UTF-8");
	 } catch (UnsupportedEncodingException e) {
	e.printStackTrace();
	}
	 return result;
	}
}


你可能感兴趣的:(aes,安全)