南兴开放平台
  1. 开发前必读
南兴开放平台
  • 开发前必读
    • 1.开发须知
    • 2.key-auth授权
    • 3. para-hmac-auth签名算法
    • 4.接口调用
    • 5.集成规范总体原则
    • 6.更新日志
    • 7.常见问题
  • ERP
    • 经销商平台
      • 经销商查询BOM子项接口
      • Bom多阶查询
      • 查询客户信息接口
      • 经销商生成U9销售订单接口
      • 同步配件库存及价格
      • 查询经销商价目表配件料品信息
    • 配件商城
      • 配件商城查库存
      • 查询料品库存价格
      • 配件商城生成销售订单
    • 用序列号查询是否存在U9系统
      POST
  • NXLINK
    • 南兴link消息发送
      POST
    • 南兴link效验Ticket
      POST
  • OA
    • 流程管理
      • 查询流程信息
      • 新建流程
  • 人事考勤
    • 2号人事
      • 获取token
  • 企查查
    • 企业信息
      • 企业高级搜索
  • 短信
    • 发送短信
      POST
  • 事件管理
    • 事件数据回调
    • 发送事件数据
      POST
  1. 开发前必读

3. para-hmac-auth签名算法

1.生成 Body 体待签名的值
获取 Body 字节数组,采用 Base64 编码得到 Content。
2.签名字段
“X-App-Id”、“X-Sequence-No”、“X- Timestamp”和“Body”作为签名字段,“Body” 的值为上一步生成的Content。
3.排序
按照 ASCII 递增排序(字母升序排序),如果第一位一样,则按照第二位,以此类推。
4.生成待签名字符串
过滤掉空值(null或空字符)的key,将排序后的参数与值组合成“参数=参数值”的格式,并且把这些参数用&字符连接起来,最后拼接“&”和APP密钥,生成待签名字符串。示例值如下:
Post:
Body=dGVzdHQ=&X-App-Id=100001&X-Sequence-No=2020010916354525600001&X-Timestamp=20200109163545256&47d57ce4266c187ea60d66279b152c4b
Get:
X-App-Id=100001&X-Sequence-No=2020010916354525600001&X- Timestamp=20200109163545256&47d57ce4266c187ea60d66279b152c4b
5.生成签名
获取待签名字符串字节数组,用SHA256生成摘要值,并进行Base64编码,得到签名字串。
签名算法说明:
POST:
Base64(
SHA256(
Body=Base64({X-App-Id}&
X-Sequence-No={X-Timestamp}&
${AppSecret}
)
)
GET:
Base64(
SHA256(
X-App-Id={X-Sequence-No}&
X-Timestamp={AppSecret}
)
)
java代码示例:

 package com.nanxing;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.TreeMap;

public class SignTest {


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

        String appId = "EX1001";
        String appKey = "dafsfdsfasdfa";

        TreeMap<String,String> headerMap = new TreeMap<>();
        //获得时间戳
        String timestamp = new SimpleDateFormat("yyyyMMddHHmmssSSS").format(new Date());
        //生成流水号
        String sequenceNo = timestamp + ((int)((Math.random()*9+1)*10000));
        headerMap.put("X-Timestamp", timestamp);
        headerMap.put("X-Sequence-No", sequenceNo);
        headerMap.put("X-App-Id", appId);

        String body = "{\n" +
                "\"context\": {\n" +
                "\"CultureName\": \"zh-CN\", \n" +
                "\"EntCode\": \"0819\",  \n" +
                "\"OrgCode\": \"100\",  \n" +
                "\"UserCode\": \"admin\"  \n" +
                "},  \n" +
                "\"bomItem\": \"10101.00001\"  \n" +
                "}";

        if (StringUtils.isNotEmpty(body)){
            headerMap.put("Body", Base64.getEncoder().encodeToString(body.getBytes()));
        }
        String sign =  sign(headerMap,appKey );
        headerMap.put( "X-Signature", sign);
        headerMap.remove("Body");

        String url = "http://api-test.nanxing.com/erp/qryBomCompentService";
        HttpResponse response = HttpUtil.createPost(url).addHeaders(headerMap).body(body).execute();
        System.out.println(response.body());
    }


    /**
     *
     * @param signMap
     * @param macKey    秘钥
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String sign(TreeMap<String, String> signMap, String macKey)  throws NoSuchAlgorithmException {
        if (MapUtils.isEmpty(signMap)){
            return "";
        }
        //签名
        String sha256 = sha256(generateSignString(signMap, macKey));
        System.out.println(sha256);
        return sha256;
    }


    /**
     * sha256加密
     * @param data 待加密数据
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String sha256(String data) throws NoSuchAlgorithmException {
        MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
        byte[] digest = messageDigest.digest(data.getBytes(StandardCharsets.UTF_8));

        return Base64.getEncoder().encodeToString(digest);
    }


    public static String generateSignString(TreeMap<String, String> signMap, String macKey) {
        if (MapUtils.isEmpty(signMap)){
            return "";
        }
        StringBuilder signStrBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : signMap.entrySet()){
            //过滤空值
            if (StringUtils.isEmpty(entry.getValue())){
                continue;
            }
            //拼接签名字段
            signStrBuilder.append(entry.getKey())
                    .append("=")
                    .append(entry.getValue())
                    .append("&");
        }
        String sign = signStrBuilder.append(macKey).toString();
        return sign;
    }
}


 

 
 
 
修改于 2024-04-21 01:42:05
上一页
2.key-auth授权
下一页
4.接口调用
Built with