用Java实现AES/CBC/PKCS7Padding加解密

开发微信小程序的时候,第三方应用服务器需要解密微信服务器给的加密数据。当时小程序官方没有给出Java实现。网上的解决方案基本都差不多,但是示例代码不够清晰,逻辑混乱,这里整理一下。

 

1. Maven引入三方包

Java SE自带的加解密工具包不支持AES/CBC/PKCS7Padding。

<dependency>
  <groupId>org.bouncycastle</groupId>
  <artifactId>bcprov-jdk15on</artifactId>
  <version>1.55</version>
</dependency>

 

2. 测试方法

①进行加解密之前注意导入支持AES/CBC/PKCS7Padding的Provider。

②Base64只是一种编码解码工具,数据编码后,便于网络上传输。跟加解密没关系。

public static void main(String[] args) throws Exception {

    //原始数据
	String data = "i am data";
    //密钥
	String sessionKey = "i am strong key ";
    //向量
	String iv = "i am iv i am iv ";
	
	//用Base64编码
	Base64.Encoder encoder = Base64.getEncoder();
	String baseData = encoder.encodeToString(data.getBytes());
	String baseSessionKey = encoder.encodeToString(sessionKey.getBytes());
	String baseIv = encoder.encodeToString(iv.getBytes());
	
    //导入支持AES/CBC/PKCS7Padding的Provider
	Security.addProvider(new BouncyCastleProvider());
		
    //获取加密数据
	String encryptedData = encrypt(baseData,baseSessionKey,baseIv);
    //通过加密数据获得原始数据
	String dataReborn = decrypt(encryptedData,baseSessionKey,baseIv);
		
    //打印解密出来的原始数据
	System.out.println(dataReborn);
		
}

 

3. 加密方法

public static String encrypt(String data,String sessionKey,String iv) throws Exception {

    //加密之前,先从Base64格式还原到原始格式
    Decoder decoder = Base64.getDecoder();
	byte[] dataByte = decoder.decode(data);
	byte[] keyByte = decoder.decode(sessionKey);
	byte[] ivByte = decoder.decode(iv);
	
    String encryptedData = null;

    //指定算法,模式,填充方式,创建一个Cipher
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");

    //生成Key对象
    Key sKeySpec = new SecretKeySpec(keyByte, "AES");
    
    //把向量初始化到算法参数
    AlgorithmParameters params = AlgorithmParameters.getInstance("AES");  
    params.init(new IvParameterSpec(ivByte));  

    //指定用途,密钥,参数 初始化Cipher对象
    cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, params);

    //指定加密
    byte[] result = cipher.doFinal(dataByte);
        
    //对结果进行Base64编码,否则会得到一串乱码,不便于后续操作
    Base64.Encoder encoder = Base64.getEncoder();
    encryptedData = encoder.encodeToString(result);

		
	return encryptedData;
}

 

4. 解密方法

public static String decrypt(String encryptedData,String sessionKey,String iv) throws Exception {

    //解密之前先把Base64格式的数据转成原始格式
	Decoder decoder = Base64.getDecoder();
	byte[] dataByte = decoder.decode(encryptedData);
	byte[] keyByte = decoder.decode(sessionKey);
	byte[] ivByte = decoder.decode(iv);
		
	String data = null;
    
    //指定算法,模式,填充方法 创建一个Cipher实例
	Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding","BC");

    //生成Key对象
    Key sKeySpec = new SecretKeySpec(keyByte, "AES");
        
    //把向量初始化到算法参数
    AlgorithmParameters params = AlgorithmParameters.getInstance("AES");  
    params.init(new IvParameterSpec(ivByte));  

    //指定用途,密钥,参数 初始化Cipher对象
    cipher.init(Cipher.DECRYPT_MODE, sKeySpec, params);

    //执行解密
    byte[] result = cipher.doFinal(dataByte);

    //解密后转成字符串
    data = new String(result);
		
    return data;
}

5. 结果

i am data

 

转载于:https://my.oschina.net/leaforbook/blog/1808360

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值