AES加密中文乱码

来源:互联网 发布:移动互联网 大数据 编辑:程序博客网 时间:2024/06/05 07:06
  前几天,使用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;}}


1 0