Solicitud POST, paso de parámetros JSON (aplicación/json, solo admite paso de parámetros de URL)
La ruta de solicitud original y los parámetros en el documento de la interfaz:
https://cx.o2o.bailingjk.net/requestpah
Cuerpo de solicitud:{“var1”:” valor1”,”var2”:”valor2”}
a. Empalme de los parámetros de solicitud ts appId y timestamp
appId=yourAppId&ts=currenttimesMillis
b. Base64 codifica la cadena json (consulte el Apéndice 3)
base64EncodedJsonStr=Base64.encodeBase64String(jsonBody.getBytes(Charset.forName("UTF-8")));
c. Use la clave de la aplicación como clave para cifrar la clave de la aplicación con AES (consulte el Apéndice 1)
encriptadoAppKey = aesEncrypt(contenido appKey, passwd appKey)
d. Empalme el parámetro json codificado en Base64 (nombre del parámetro: base64JsonBody) y la clave de aplicación cifrada con AES en el parámetro de solicitud (integrado en el paso a)
appId=yourAppId&ts=currenttimesMillis&base64JsonBody=base64EncodedJsonStr&appKey=encryptedAppKey
e. Realice el cálculo de resumen MD5 en los parámetros de solicitud (construidos en el paso d) para obtener firmas de huellas dactilares (consulte el Apéndice 2)
MD5Sign=MD5Digest.diget(cadenaconsulta)
F. Para los parámetros de solicitud (integrados en el paso d), elimine los parámetros appKey y base64JsonBody y agregue el parámetro de firma de huella digital sign= MD5Sign
Nota: los parámetros appKey y base64JsonBody solo se usan como factores de impacto del resumen MD5 y se eliminan directamente después de obtener el resumen MD5.
appId=yourAppId&ts=currenttimesMillis&sign=MD5Sign
g. Agregue los parámetros de la solicitud (construidos en el paso f) a la ruta de la solicitud original (el parámetro json codificado en Base64 solo se usa como un factor influyente para obtener la firma del resumen, y el parámetro json en el cuerpo de la solicitud permanece sin cambios)
Ruta de solicitud final y parámetros:
https://cx.o2o.bailingjk.net/requestpah?appId=yourAppId&ts=currenttimesMillis&sign=MD5Sign
Cuerpo de solicitud:{“var1”:” valor1”,”var2”:”valor2”}
Clase de herramienta de llamada ThirdAppRequestUtil
/**
* @BelongsProject: datainterface
* @BelongsPackage: com.msunsoft.datainterface.controller.mobile.util
* @Author: xiajinqian
* @CreateTime: 2023-06-19 14:16
* @Description: 鉴权工具类
*/
package com.msunsoft.datainterface.controller.mobile.util;
import cn.hutool.json.JSONUtil;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.Charset;
import java.util.Base64;
import java.util.HashMap;
public class ThirdAppRequestUtil {
public static String craeteRequest(String appId, String appKey, HashMap<String, String> params, String url){
//构造路径参数
StringBuilder sb = new StringBuilder();
for (String key : params.keySet()) {
sb.append(key).append("=").append(params.get(key)).append("&");
}
//添加时间戳参数ts=当前时间戳
String appIdAndTimeStamp =sb+"appId=" + appId + "&ts="+System.currentTimeMillis();
// 使用appKey作为密钥对appKey本身进行AES加密
String encryptedAppKey = CrossPlatformAesMd5Utils.aesEncrypt(appKey,appKey);
//拼接需签名的参数
String URL=appIdAndTimeStamp + "&appKey=" +encryptedAppKey;
//使用MD5对URL进行签名
String md5 = CrossPlatformAesMd5Utils.md5Encrypt(URL);
//拼接url
String s = url + "?"+appIdAndTimeStamp + "&sign=" + md5;
return s;
}
public static String craeteRequest(String appId, String appKey, HashMap<String, String> params, String url,String json){
//构造路径参数
StringBuilder sb = new StringBuilder();
for (String key : params.keySet()) {
sb.append(key).append("=").append(params.get(key)).append("&");
}
String encode = Base64.getEncoder().encodeToString(json.getBytes(Charset.forName("UTF-8")));
//添加时间戳参数ts=当前时间戳
String appIdAndTimeStamp =sb+"appId=" + appId + "&ts="+System.currentTimeMillis();
// 使用appKey作为密钥对appKey本身进行AES加密
String encryptedAppKey = CrossPlatformAesMd5Utils.aesEncrypt(appKey,appKey);
//拼接需签名的参数
String URL=appIdAndTimeStamp +"&base64JsonBody="+encode+"&appKey=" +encryptedAppKey;
//使用MD5对URL进行签名
String md5 = CrossPlatformAesMd5Utils.md5Encrypt(URL);
//拼接url
String s = url + "?"+appIdAndTimeStamp + "&sign=" + md5;
return s;
}
public static String postRequest(String url, String jsonInput){
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(jsonInput, headers);
ResponseEntity<String> response = restTemplate.postForEntity(url, request, String.class);
return response.getBody();
}
}
Clase de herramienta CrossPlatformAesMd5Utils
package com.msunsoft.datainterface.controller.mobile.util;
import org.springframework.beans.factory.annotation.Autowired;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.UUID;
/**
* @ClassName: CrossPlatformAesMd5Utils
* @Description: 实现跨平台的AES加密解密算法
* @author: @author xiangguangdong
* @date: 2020/11/4 20:19
*/
public class CrossPlatformAesMd5Utils {
private static final String BYTES_CHARTSET = "utf-8";
private static final String SECRET_KEY_SPEC_ALGORITHM = "AES";
public static final String VIPARA = "zEXaPrpd67fPrkMr";
public static final String CIPHER_TYPE = "AES/CBC/PKCS5Padding";
public static final String DIGEST_ALGORITHM = "MD5";
public CrossPlatformAesMd5Utils() {
}
public static String aesEncrypt(String source, String key) {
return aes(source, key, 1);
}
public static String aesDecrypt(String source, String key) {
return aes(source, key, 2);
}
/**
* MD5摘要
* @param source
* @return
*/
public static String md5Encrypt(String source) {
try {
MessageDigest mdInstance = MessageDigest.getInstance(DIGEST_ALGORITHM);
byte[] sourceBytes = source.getBytes(BYTES_CHARTSET);
byte[] digestBytes = mdInstance.digest(sourceBytes);
return parseByte2HexStr(digestBytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static String aes(String source, String key, int type) {
try {
byte[] keyBytes = key.getBytes("utf-8");
SecretKeySpec skeySpec = new SecretKeySpec(keyBytes, "AES");
byte[] ivBytes = "zEXaPrpd67fPrkMr".getBytes("utf-8");
IvParameterSpec iv = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(type, skeySpec, iv);
byte[] sourceBytes;
byte[] decrypted;
if (type == 1) {
sourceBytes = source.getBytes("utf-8");
decrypted = cipher.doFinal(sourceBytes);
return parseByte2HexStr(decrypted);
} else {
sourceBytes = parseHexStr2Byte(source);
decrypted = cipher.doFinal(sourceBytes);
return new String(decrypted, "utf-8");
}
} catch (Exception var10) {
var10.printStackTrace();
return null;
}
}
public static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (byte b : buf) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1) {
return null;
} else {
byte[] result = new byte[hexStr.length() / 2];
for(int i = 0; i < hexStr.length() / 2; ++i) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte)(high * 16 + low);
}
return result;
}
}
/**
* 获取随机UUID
* @return
*/
public static String getUUID(){
return UUID.randomUUID().toString();
}
public static void main(String[] args) {
String source = "GorDVC6PVhcLM1RR";
String key = "H8PFP050P575yqWP";
String encrypted = aesEncrypt(source, key);
System.out.println(encrypted);
String decrypted = aesDecrypt(encrypted, key);
System.out.println(decrypted);
}
}