Java Http接口加签、验签操作方法_java

1、业务背景

最近接触了一些电商业务,发现在处理电商业务接口时,比如淘宝、支付类接口,接口双方为了确保数据参数在传输过程中未经过篡改,都需要对接口数据进行加签,然后在接口服务器端对接口参数进行验签,确保两个签名是一样的,验签通过之后再进行业务逻辑处理。我们这里主要介绍一下处理思路,至于签名算法我不做过多介绍,网上一大堆。

2、处理思路

双方约定好,参数按特定顺序排列,比如按首字母的顺序排列,如url:http://xxx/xxx.do?a=wersd&b=sd2354&c=4&signature=XXXXXXXXXXXX(signature为传入的签名),等你拿到入参后,将参数串a=wersd&b=sd2354&c=4按你们约定的签名规则,自己用md5加签一次,然后和入参的signature值对比,以确认调用者是否合法,这就是接口签名验证的思路。

3、实例练习

接口双方经过沟通,对接口达成如下共识:

1、注意事项,主要指接口的的协议、传入参数类型、签名算法、文件格式等说明

2、下面是一个电商业务接口的真实案例,双方约定好了接口URL、业务参数、固定参数、签名以及返回数据格式

接口调用时,接口调用方代码如下(仅供参考):

package com.pcmall;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

public class APITest {
  static String TEST_URL = "待定";
  static String TEST_KEY = "待定";
  static String TEST_SEC = "待定";					

  public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException {
    String result = getResult(TEST_URL, getReqParam());
    System.out.print(result);
  }					

  private static String getReqParam() throws UnsupportedEncodingException, NoSuchAlgorithmException {
  	TreeMap<String, String> req = new TreeMap<String, String>();
    req.put("a", TEST_KEY);
    req.put("f", "json");
    req.put("l", "zh_CN");
    req.put("m", "zhongan.repair.query");
    req.put("v", "1.0");
    req.put("i", "" + System.currentTimeMillis() / 1000);
    req.put("params", "{\"assignNo\":\"TEST018\"}");
    req.put("s", sign(req, null, TEST_SEC));					

    StringBuilder param = new StringBuilder();
    for (Iterator<Map.Entry<String, String>> it = req.entrySet().iterator(); it.hasNext();) {
      Map.Entry<String, String> e = it.next();
      param.append("&").append(e.getKey()).append("=").append(URLEncoder.encode(e.getValue(), "UTF-8"));
    }					

    return param.toString().substring(1);
  }					

  private static String sign(Map<String, String> paramValues, List<String> ignoreParamNames, String secret) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    StringBuilder sb = new StringBuilder();
    List<String> paramNames = new ArrayList<String>(paramValues.size());
    paramNames.addAll(paramValues.keySet());
    if (ignoreParamNames != null && ignoreParamNames.size() > 0) {
      for (String ignoreParamName : ignoreParamNames) {
        paramNames.remove(ignoreParamName);
      }
    }
    Collections.sort(paramNames);					

    sb.append(secret);
    for (String paramName : paramNames) {
      sb.append(paramName).append(paramValues.get(paramName));
    }
    sb.append(secret);					

    MessageDigest md = MessageDigest.getInstance("SHA-1");
    return byte2hex(md.digest(sb.toString().getBytes("UTF-8")));
  }					

  private static String byte2hex(byte[] bytes) {
    StringBuilder sign = new StringBuilder();
    for (int i = 0; i < bytes.length; i++) {
      String hex = Integer.toHexString(bytes[i] & 0xFF);
      if (hex.length() == 1) {
        sign.append("0");
      }
      sign.append(hex.toUpperCase());
    }
    return sign.toString();
  }					

  private static String getResult(String urlStr, String content) {
    URL url = null;
    HttpURLConnection connection = null;
    try {
      url = new URL(urlStr);
      connection = (HttpURLConnection) url.openConnection();
      connection.setDoOutput(true);
      connection.setDoInput(true);
      connection.setRequestMethod("POST");
      connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
      connection.setUseCaches(false);
      connection.connect();					

      DataOutputStream out = new DataOutputStream(connection.getOutputStream());
      out.write(content.getBytes("UTF-8"));
      out.flush();
      out.close();					

      BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
      StringBuffer buffer = new StringBuffer();
      String line = "";
      while ((line = reader.readLine()) != null) {
        buffer.append(line);
      }
      reader.close();					

      return buffer.toString();
    } catch (IOException e) {
      e.printStackTrace();
    } finally {
      if (connection != null) {
        connection.disconnect();
      }
    }					

    return null;
  }	

}

服务器端代码如下(仅供参考):

@RequestMapping("/repairTakeOrder")
	@ResponseBody
	public ResponseVO repairTakeOrder(@RequestBody String jsonStr) {
		logger.info("repairTakeOrder入参:" + jsonStr);

		ResponseVO responseVO = null;
		try {
			RepairOrder repairOrder = JackJsonUtil.toBean(jsonStr,
					RepairOrder.class);
			TreeMap<String, String> paramsMap = new TreeMap<String, String>();
			paramsMap.put("gsxx01", repairOrder.getGsxx01());
			paramsMap.put("orderType", repairOrder.getOrderType().toString());
			paramsMap.put("serviceNo", repairOrder.getServiceNo());
			paramsMap.put("vipCard", repairOrder.getVipCard());
			paramsMap.put("customerName", repairOrder.getCustomerName());
			paramsMap.put("customerPhone", repairOrder.getCustomerPhone());
			paramsMap.put("customerTel", repairOrder.getCustomerTel());
			paramsMap.put("province", repairOrder.getProvince());
			paramsMap.put("city", repairOrder.getCity());
			paramsMap.put("county", repairOrder.getCounty());
			paramsMap.put("address", repairOrder.getAddress());
			paramsMap.put("salerCode", repairOrder.getSalerCode());
			paramsMap.put("salerName", repairOrder.getSalerName());
			paramsMap.put("storeCode", repairOrder.getStoreCode());
			paramsMap.put("storeName", repairOrder.getStoreName());
			paramsMap.put("site", repairOrder.getSite());

			paramsMap.put("siteDesp", repairOrder.getSiteDesp());
			paramsMap.put("engineerCode", repairOrder.getEngineerCode());
			paramsMap.put("engineerName", repairOrder.getEngineerName());
			if (repairOrder.getServiceDate() != null) {
				paramsMap.put("serviceDate",
						DateUtils.formatDate(repairOrder.getServiceDate()));
			}

			if (repairOrder.getSalePrice() != null) {
				paramsMap.put("salePrice", repairOrder.getSalePrice()
						.toString());
			}

			paramsMap.put("profitCenter", repairOrder.getProfitCenter());
			paramsMap.put("costCenter", repairOrder.getCostCenter());
			paramsMap.put("gsxx02", repairOrder.getGsxx02());
			paramsMap.put("returnReason", repairOrder.getReturnReason());
			if (repairOrder.getOriOrder() != null) {
				paramsMap.put("oriOrder", repairOrder.getOriOrder().toString());
			}

			if (repairOrder.getOriServiceNo() != null) {
				paramsMap.put("oriServiceNo", repairOrder.getOriServiceNo());
			}

			// 拼接签名原串(a=1&b=2)
			String paramSrc = RequestUtils.getParamSrc(paramsMap);
			logger.info("签名原串:" + paramSrc);
			//进行验签操作
			if (SignUtils.verifymd5(paramSrc, repairOrder.getSign())) {
				//处理业务逻辑
				responseVO=erpServiceImpl.repairTakeOrder(repairOrder);

			} else {
				responseVO = new ResponseVO();
				responseVO.setSuccess(false);
				responseVO.setErrorMsg("验签失败");
			}

		} catch (Exception e) {
			logger.error("", e);
			responseVO = new ResponseVO();
			responseVO.setSuccess(false);
			responseVO.setErrorMsg(StringUtils.isNotBlank(e.getMessage()) ? e.getMessage() : "后台异常");
		}
		return responseVO;

	}

以上这篇Java Http接口加签、验签操作方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, 验签
接口加签
java api接口签名验证、java接口参数校验、java 接口token验证、java短信验证码接口、java接口签名验证,以便于您获取更多的相关知识。

时间: 2024-12-09 22:15:36

Java Http接口加签、验签操作方法_java的相关文章

php对接java现实加签验签的实例_php实例

我实现的方法,主要是把java生成的密钥转为php能识别的pem格式的密钥,其它的加签.验签采用调用openssl内置签名方法. java生成的密钥主要是字符串:而pem格式密钥是以64位为一行,并且带有如下头和尾的文件格式,然后php再去取得相对应pem格式字符串. pem格式密钥 -----BEGIN PUBLIC KEY----- //64chars一行(多行) -----END PUBLIC KEY----- -----BEGIN RSA PRIVATE KEY----- //64cha

php对接java现实加签验签的实例

我实现的方法,主要是把java生成的密钥转为php能识别的pem格式的密钥,其它的加签.验签采用调用openssl内置签名方法. java生成的密钥主要是字符串:而pem格式密钥是以64位为一行,并且带有如下头和尾的文件格式,然后php再去取得相对应pem格式字符串. pem格式密钥 -----BEGIN PUBLIC KEY----- //64chars一行(多行) -----END PUBLIC KEY----- -----BEGIN RSA PRIVATE KEY----- //64cha

将Java程序与数据库进行连接的操作方法_java

一个网络关系数据库应用系统是一个三层次结构.客户机与服务器采用网络连接,客户机端应用程序按通信协议与服务器端的数据库程序通信:数据库服务程序通过SQL命令与数据库管理系统通信. Java程序与数据库连接方法有两种.一种是使用JDBC-ODBC桥接器与数据库连接,一种是用纯Java的JDBC驱动程序实现与数据库连接.使用JDBC-ODBC 桥接器与数据库连接 Java程序使用JDBC-ODBC 桥接器与数据库连接,Java程序与数据库通信的过程是: 先由数据库应用程序向ODBC驱动管理器发出API

php rsa 加密,解密,签名,验签详解_php技巧

php rsa 加密,解密,签名,验签 由于对接第三方机构使用的是Java版本的rsa加解密方法,所有刚开始在网上搜到很多PHP版本的rsa加解密,但是对接java大多都不适用. 以下php版本是适用于对接java接口,java适用密钥再php语言使用是需要添加 -----BEGIN CERTIFICATE----- -----END CERTIFICATE----- 使用密钥:加密公钥  public_key.cer 解密私钥  private_key.key 签名私钥 sign_key.ke

实例-ping++ java验签(签名,公钥,charge)怎么获取

问题描述 ping++ java验签(签名,公钥,charge)怎么获取 这是官网demo package example;import java.io.FileInputStream;import java.security.InvalidKeyException;import java.security.KeyFactory;import java.security.NoSuchAlgorithmException;import java.security.PublicKey;import

工行验签问题,求做过工行支付接口的人帮忙看看。本人不胜感激。

问题描述 工行验签问题,求做过工行支付接口的人帮忙看看.本人不胜感激. 工行B2C支付成功之后的解析验签报错:javax.crypto.BadPaddingException: unknown block type ,i = -1.i = 0 时才是验签正确,求做过的大神指导一下 .. 解决方案 帮顶!同求!和楼主一样也被工行借口无限蹂躏

农行支付成功,回调验签失败

问题描述 农行支付成功,回调验签失败 农行支付成功,回调时 String msg = request.getParameter("MSG"); try { PaymentResult pr = new PaymentResult(msg); if(pr.isSuccess()){ System.out.println("成功"); }else{ System.out.println("失败"); } } catch (TrxException e

验签

1,验签的输入 签名的验证有3个输入: (1)密码(用于签名的种子);(2)签名本身;(3)公钥 2,验签的应用场景 邮件的加密发送 具体步骤: 插上key,key中包含私钥和签名; 弹框要求输入密码; 使用公钥和签名来验证签名,如果密码不对,则验签失败; 若验签成功,则产生随机秘钥E; 使用随机秘钥E加密邮件内容M,得到M2; 使用对方的公钥对E进行加密,得到E2; 把M2,E2,发送给对方. 对方收到之后,使用私钥对E2,进行解密,得到E; 使用E对M2进行解密得到明文邮件.

md5-MD5认证 验签失败 解决认证问题

问题描述 MD5认证 验签失败 解决认证问题 抓包修改数据后,总是显示验签失败,应该是MD5认证解决不了,请问这个有办法解决吗 解决方案 不知道在弄什么,按文档要求的加密算法来进行加密和验签