package com.gillion.worldex.util; import com.fasterxml.jackson.databind.ObjectMapper; import com.otechsolution.out.entity.integration.Inventory; import com.otechsolution.web.signer.util.AesEncryptUtils; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.RandomStringUtils; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.DigestUtils; import org.springframework.web.client.RestTemplate; import java.math.BigDecimal; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.Arrays; @Slf4j public class Demo { public static void main(String[] args) throws Exception { String appId = ""; String appSecret = ""; long timeMillis = System.currentTimeMillis(); String nonce = RandomStringUtils.randomAlphanumeric(16); Inventory req = getInventory(); String content = new ObjectMapper().writeValueAsString(Arrays.asList(req)); log.info("请求对象:[{}]", content); String encryptContent = AesEncryptUtils.encrypt(content, appSecret, nonce); log.info("AES加密串:[{}]", encryptContent); // appId+nonce+timestamp+secret StringBuilder builder = new StringBuilder(); builder.append("appId=").append(appId).append("&") .append("nonce=").append(nonce).append("&") .append("timestamp=").append(timeMillis).append("&") .append(appSecret); log.info("MD5源串:[{}]", builder); String sign = DigestUtils.md5DigestAsHex(builder.toString().getBytes(StandardCharsets.UTF_8)); log.info("MD5目标串:[{}]", sign); HttpHeaders headers = new HttpHeaders(); headers.add("appId", appId); headers.add("nonce", nonce); headers.add("timestamp", String.valueOf(timeMillis)); headers.add("sign", sign); MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8"); headers.setContentType(type); log.info("request header:[{}]", headers); // 转义加密串中的特殊字符 String encode = URLEncoder.encode(encryptContent, "utf-8"); HttpEntity<String> httpEntity = new HttpEntity<>(encode, headers); RestTemplate restTemplate = new RestTemplate(); String url = ""; ResponseEntity<String> response = restTemplate.postForEntity(url, httpEntity, String.class); String body = response.getBody(); String resNonce = response.getHeaders().get("nonce").get(0); byte[] decrypt = AesEncryptUtils.decrypt(body, appSecret, resNonce); log.info("接口响应:[{}]", new String(decrypt)); } private static Inventory getInventory() { Inventory req = new Inventory(); req.setLimitDate("2018-02-02 18:00:00"); req.setStockDate("2018-02-02 18:00:00"); req.setCiqCode("1"); req.setContrItem(BigDecimal.ZERO); req.setCopGNo("2"); req.setGModel("3"); req.setGName("4"); req.setGrossWt(BigDecimal.ZERO); req.setGUnit("5"); req.setHsCode("6"); req.setNetWt(BigDecimal.ZERO); req.setOriginCountryCode("9"); req.setProductType(0); req.setQty(BigDecimal.ZERO); req.setQty1(BigDecimal.ZERO); req.setQty2(BigDecimal.ZERO); req.setStockType(0); req.setTradeCurr("10"); req.setTradeTotal(BigDecimal.ZERO); req.setUnit1("11"); req.setUnit2("12"); req.setUnitPrice(BigDecimal.ZERO); req.setWhLoc("13"); req.setWhLoc("14"); return req; } }
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------加密 解密 demo
package com.gillion.worldex.util;
import org.apache.commons.lang3.RandomStringUtils;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.ws.spi.http.HttpHandler;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
/**
* 前后端数据传输加密工具类
* 如果加密过程中抛出异常:java.security.InvalidKeyException: Illegal key size
* 请按照https://blog.youkuaiyun.com/qq_41906281/article/details/109492814解决
*
* @author ericyuan
*/
public class AesEncryptUtils {
//参数分别代表 算法名称/加密模式/数据填充方式
private static final String ALGORITHMSTR = "AES/CBC/PKCS5Padding";
//秘钥算法
private static final String KEY_ALGORITHM = "AES";
public static byte[] getBytes(String string) {
return string.getBytes(StandardCharsets.UTF_8);
}
/**
* 加密字符串
*
* @param data 待加密字符串
* @param key 加密秘钥
* @param ivParam iv参数秘钥,必须16字节长度
* @return
* @throws Exception
*/
public static String encrypt(String data, String key, String ivParam) throws Exception {
byte[] keyBytes = getBytes(key);
byte[] ivBytes = getBytes(ivParam);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, iv);
byte[] dataBytes = getBytes(data);
byte[] encrypted = cipher.doFinal(dataBytes);
return Base64.getEncoder().encodeToString(encrypted);
}
public static byte[] decrypt(String sign, String key, String ivParam) throws Exception {
return decrypt(getBytes(sign), key, ivParam);
}
/**
* 解密字符串
*
* @param signBytes 待解密数据
* @param key 解密key
* @param ivParam iv解密参数秘钥,必须16字节长度
* @return
* @throws Exception
*/
public static byte[] decrypt(byte[] signBytes, String key, String ivParam) throws Exception {
byte[] keyBytes = getBytes(key);
byte[] ivBytes = getBytes(ivParam);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, KEY_ALGORITHM);
Cipher cipher = Cipher.getInstance(ALGORITHMSTR);
IvParameterSpec iv = new IvParameterSpec(ivBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, iv);
byte[] encrypted1 = Base64.getMimeDecoder().decode(signBytes);
return cipher.doFinal(encrypted1);
}
public static void main(String[] args) throws Exception {
String key = "897D660077BA86D39081B984048E0D95";
String ivParam = RandomStringUtils.randomAlphanumeric(16);
String content = "{\"address\":\"上海市老街\",\"id\":1001,\"name\":\"张三\"}";
System.out.println(content + " 长度为" + content.length());
long lStart = System.currentTimeMillis();
String enString = encrypt(content, key, ivParam);
System.out.println("加密后的字串是:" + enString + "长度为" + enString.length());
System.out.println("加密耗时:" + (System.currentTimeMillis() - lStart) + "毫秒");
lStart = System.currentTimeMillis();
String decrypt = new String(decrypt(enString, key, ivParam), "UTF-8");
System.out.println("解密后的字串是:" + decrypt + " 长度为" + decrypt.length());
System.out.println("解密耗时:" + (System.currentTimeMillis() - lStart) + "毫秒");
}
}