# 签名算法

#### **签名过程**

- 拼接报文参数  
    除sign参数外的所有参数按照ASCII顺序排序后，以"参数名1=参数值1&amp;参数名2=参数值2"的方式拼接所有参数
- 拼接签名 mwMacKey  
    最后在尾部拼接双方约定的密钥"KEY=xxxxx"，  
    因调用downloadKey接口前，并未获得mwMacKey，故使用指定KEY签名  
    因调用signin接口前，并未获得mwMacKey，故使用mwTmk签名
- 签名值计算  
    MD5-32加密后再转成HEX大写格式，即为签名值，并赋给sign参数。
- 注  
    当参数值为null或为空时不参与签名串拼接

#### **示例报文**

```
 {
     "action" : "inquiry",
     "deviceNo" : "POS01",
     "shopNo" : "CN123456",
     "brand" : "663",
     "body" : "ewogICAgICAgICAidHJhY2VObyI6ICI5OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW5hbFRyYWNlTm8iOiAiOTkwMDAwMDkxMDAwMTAxMDE3MzIxMjQiCiAgICAgfQ==",
     "mwVersion" : "20161010",
     "ptlVersion" : "20161010",
     "posVersion" : "20161010",
     "timestamp" : "1483372334",
     "sign" : "F38545F4D74B5C10A9EBBC053ED9D1CF"
 }

```

#### **签名mwMacKey密钥**

```
94365019BBF9CEEAB0DF658E67754A70

```

#### **拼接报文参数**

```
action=inquiry&body=ewogICAgICAgICAidHJhY2VObyI6ICI5OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW5hbFRyYWNlTm8iOiAiOTkwMDAwMDkxMDAwMTAxMDE3MzIxMjQiCiAgICAgfQ==&brand=663&deviceNo=POS01&mwVersion=20161010&posVersion=20161010&ptlVersion=20161010&shopNo=CN123456&timestamp=1483372334

```

#### **拼接签名KEY**

```
action=inquiry&body=ewogICAgICAgICAidHJhY2VObyI6ICI5OTAwMDAwOTEwMDAxMDEwMTczMjEyMyIsCiAgICAgICAgICJvcmlnaW5hbFRyYWNlTm8iOiAiOTkwMDAwMDkxMDAwMTAxMDE3MzIxMjQiCiAgICAgfQ==&brand=663&deviceNo=POS01&mwVersion=20161010&posVersion=20161010&ptlVersion=20161010&shopNo=CN123456&timestamp=1483372334&KEY=94365019BBF9CEEAB0DF658E67754A70

```

#### **签名值计算**  
F38545F4D74B5C10A9EBBC053ED9D1CF

#### **Java代码示例**

```

Map<String, String> map = new TreeMap<>();
map.put("action", "downloadKey");
map.put("deviceNo", "CN999999");
map.put("shopNo", "CN999999");
map.put("brand", "1458");
map.put("body", "JXU2RDRCJXU4QkQ1JXU1MTg1JXU1QkI5JTIwJXU2RDRCJXU4QkQ1JXU1MTg1JXU1QkI5");
map.put("mwVersion", "20170214");
map.put("ptlVersion", "20170214");
map.put("posVersion", "20170214");
map.put("timestamp", "1483372334");

StringBuilder buffer = new StringBuilder();
for (Map.Entry<String, String> item : map.entrySet()) {
    buffer.append(item.getKey()).append("=").append(item.getValue()).append("&");
}
buffer.append("KEY=").append("F42616614BDC0000161EF06C04061484");
String checkSign = DESCoder.getInstance().encryptMD5(buffer.toString(), "UTF-8").toUpperCase();
System.out.println(buffer.toString());
System.out.println(checkSign);

输出:
action=downloadKey&body=JXU2RDRCJXU4QkQ1JXU1MTg1JXU1QkI5JTIwJXU2RDRCJXU4QkQ1JXU1MTg1JXU1QkI5&brand=1458&deviceNo=CN999999&mwVersion=20170214&posVersion=20170214&ptlVersion=20170214&shopNo=CN999999&timestamp=1483372334&KEY=F42616614BDC0000161EF06C04061484

824AE098F6135CF50A824BAE220379C6

```

<footer class="page-footer" id="bkmrk-"></footer>