生成规则:
请求参数按照字母排序,key+value+requestBody的md5值,然后用app_secrete hmac256加密
生成代码:
@Test
public void test() throws Exception {
String appid="appid";
long time=Instant.now().toEpochMilli();
System.out.println("time is:"+time);
String sign="";
Map<String,String> phone=new HashMap<>();
// phone.put("phone","11234");
phone.put("phone","13100000000");
MockHttpServletRequest request=new MockHttpServletRequest();
request.setParameter("appid",appid);
request.setParameter("t",String.valueOf(time));
request.setParameter("sign",sign);
request.setContentType("application/json");
request.setContent(CommonUtils.toJson(phone).getBytes());
Map<String,String[]> paramMap=request.getParameterMap();
//获取md5值
String bodyMd5=getMd5(request);
//获取签名sign
sign=getSign(paramMap,bodyMd5);
//发送请求
String url = "/test";
MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get(url)
.contentType(MediaType.APPLICATION_JSON)
.param("appid",appid)
.param("t",String.valueOf(time))
.param("sign",sign)
.content(CommonUtils.toJson(phone)))
.andExpect(MockMvcResultMatchers.status().is(200))
.andReturn();
String res = result.getResponse().getContentAsString();
System.out.println("res is:"+res);
}
private String getMd5(MockHttpServletRequest request){
HttpServletRequest httpRequest=(HttpServletRequest)request;
byte[] body = null;
Map<String,String[]> map=request.getParameterMap();
System.out.println("map is :"+CommonUtils.toJson(map));
MultiReadRequestWrapper wrappedRequest = new MultiReadRequestWrapper(httpRequest);
try (InputStream inputStream = wrappedRequest.getInputStream()) {
final int size = inputStream.available();
body = new byte[size];
inputStream.read(body);
} catch (Exception e) {
System.out.println("Error reading the request body...");
}
String md5 = StringUtils.EMPTY;
if (!Objects.isNull(body)) {
try {
md5 = outfox.edd.commoncredit.util.CommonUtils.getMd5Hex(body);
System.out.println("body md5 is :"+ md5 + " body is :"+ new String(body));
} catch (Exception e) {
System.out.println("generate md5 error,"+e);
}
}
return md5;
}
private String getSign(Map<String, String[]> params, String md5) throws InvalidKeyException, NoSuchAlgorithmException {
final TreeMap<String, String> sequenceParams = new TreeMap<>();
String sign = StringUtils.EMPTY;
String appId = StringUtils.EMPTY;
for (Map.Entry<String, String[]> stringEntry : params.entrySet()) {
String k = stringEntry.getKey();
String[] v = stringEntry.getValue();
if (Constant.PARAM_SIGN.equals(k)) {
sign = v[0];
continue;
}
if (Constant.PARAM_APP_ID.equals(k)) {
appId = v[0];
}
for (String s : v) {
sequenceParams.put(k, s);
}
}
StringBuilder input = new StringBuilder();
sequenceParams.forEach((k, v) -> input.append(k).append(v));
input.append(md5);
String secrete = "secret";
String signature= sign(input.toString().toLowerCase(), secrete);
System.out.println("sign is "+signature);
return signature;
}
/**
* HmacSHA256加密
* @param message 消息
* @param secret 秘钥
* @return 加密后字符串
*/
public String sign(String message, String secret) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchAlgorithmException {
Mac sha256hmac = Mac.getInstance("HmacSHA256");
SecretKeySpec secret_key = new SecretKeySpec(secret.getBytes(), "HmacSHA256");
sha256hmac.init(secret_key);
byte[] bytes = sha256hmac.doFinal(message.getBytes());
String hash = byteArrayToHexString(bytes);
return hash;
}
/**
* 将加密后的字节数组转换成字符串
*
* @param b 字节数组
* @return 字符串
*/
public String byteArrayToHexString(byte[] b) {
StringBuilder hs = new StringBuilder();
String stmp;
for (int n = 0; b!=null && n < b.length; n++) {
stmp = Integer.toHexString(b[n] & 0XFF);
if (stmp.length() == 1) {
hs.append('0');
}
hs.append(stmp);
}
return hs.toString().toLowerCase();
}