AES对称加密工具Java实现,与iOS加密互通
用户登陆的验证信息需要与前端互传,采用一种简单的加密手段。在开发过程中很快实现了与安卓的加密互通,但与ios的打通踩到个大坑, 详见代码中的注释和文后的链接。
有怀疑到加密位数的问题,java如果要使用256位的密钥要修改基础jar包,最终没有采用。
(Java本身限制密钥的长度最多128位,而AES256需要的密钥长度是256位,因此需要到Java官网上下载一个Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files。在Java SE的下载页面下面的Additional Resources那里会有下载链接。下载后打开压缩包,里面有两个jar文件。把这两个jar文件解压到JRE目录下的lib/security文件夹,覆盖原来的文件。这样Java就不再限制密钥的长度了。)
package cipher; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; public class AESCodeUtil { /** * 密钥,必须16位 */ private static final String IV_STRING = "1234567890abcdef"; private static Base64 base64 = new Base64(); private static String encryptAES(String content, String key) throws Exception { byte[] byteContent = content.getBytes("UTF-8"); // 注意,为了能与 iOS 统一 // 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成 byte[] enCodeFormat = key.getBytes(); SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES"); byte[] initParam = IV_STRING.getBytes(); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); // 指定加密的算法、工作模式和填充方式 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encryptedBytes = cipher.doFinal(byteContent); return new String(base64.encode(encryptedBytes)); } private static String decryptAES(String content, String key) throws Exception { byte[] encryptedBytes = base64.decode(content); byte[] enCodeFormat = key.getBytes(); SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, "AES"); byte[] initParam = IV_STRING.getBytes(); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec); byte[] result = cipher.doFinal(encryptedBytes); return new String(result, "UTF-8"); } /** * 用于加密 * @param content * @return */ public static String base64convert(String content){ String str1 = content.replaceAll("/", "_"); return str1.replaceAll("\+", "-"); } /** * 用于解密 * @param content * @return */ public static String base64convert2(String content){ String str1 = content.replaceAll("-", "\+"); return str1.replaceAll("_", "/"); } private static String encode(String content, String key){ try { return base64convert(encryptAES(content,key)); } catch (Exception e) { e.printStackTrace(); } return null; } private static String decode(String content, String key){ try { return decryptAES(base64convert2(content), key); } catch (Exception e) { e.printStackTrace(); } return null; } public static String decode(String code){ return decode(code,IV_STRING); } public static String encode(String code){ return encode(code,IV_STRING); } public static void main(String[] args) { String content = "code_12345678901234567890"; String coded = encode(content); System.out.println("密文:" + coded); String origin = decode(coded); System.out.println("原文:" + origin); } }
另附两个别人踩坑的经历
http://dditblog.com/itshare_603.html
http://www.cnblogs.com/mantgh/p/4244891.html
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。