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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值