//appSecret
private static String appSecret = "aaaa";
private static String token = "bbbb"; //token
public static void main(String[] args) throws Exception
{
Map<String, String> textParams = new HashMap<String, String>();
// 添加协议级请求参数
textParams.put("method", apiName);
textParams.put("version", "3.0");
textParams.put("appKey", appKey);
textParams.put("format", "json");
textParams.put("timestamp", new Date().getTime()+"");
textParams.put("token", token);
textParams.put("type", "sync");
String requestBody =
"{\"requestId\":\"00\"," +
"\"deviceType\":\"0\",\"invoiceTypeCode\":\"0\",\"machineNo\":\"00\","
+
"\"sellerTaxNo\":\"0\"," +
"\"apiName\":\"baiwang.tax.monitor.query\"," +
"\"taxNo\":\"0\",\"methodCode\":\"02\"}";
String signString = signTopRequest(textParams, appSecret, requestBody);//签名参
数
System.out.println(signString);
}
/**
* 给 TOP 请求签名。
*
* @param params 所有字符型的 TOP 请求参数
* @param secret 签名密钥
* @return 签名
* @throws Exception
*/
public static String signTopRequest(Map<String, String> params, String secret, String
body) throws Exception
{
// 第一步:检查参数是否已经排序
ArrayList<String> keys = new ArrayList<String>(params.keySet());
Collections.sort(keys);
// 第二步:把所有参数名和参数值串在一起
StringBuilder query = new StringBuilder();
query.append(secret);
for (String key : keys)
{
String value = params.get(key);
if (!isNull(key) && !isNull(value))
{
query.append(key).append(value);
}
}
body.replaceAll("\n","");
body.replaceAll("\t","");
body.replaceAll("\r","");
query.append(body);
query.append(secret);
// 第三步:使用 MD5 加密
byte[] bytes;
MessageDigest md5 = null;
try
{
md5 = MessageDigest.getInstance("MD5");
}
catch (NoSuchAlgorithmException ignored)
{
throw new Exception(ignored);
}
bytes = md5.digest(query.toString().getBytes("UTF-8"));
// 第四步:把二进制转化为大写的十六进制
StringBuilder sign = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(b & 0xFF);
if (hex.length() == 1) {
sign.append("0");
}
sign.append(hex.toUpperCase());
}
return sign.toString();
}
public static boolean isNull(String str)
{
return (str==null || "".equals(str)?true:false);
}
<?php
$appSecret = "aaaa";
$token = "bbbb";
$textParams = array(
'method' => $apiName,
'version' => '3.0',
'appKey' => $appKey,
'format' => 'json',
'timestamp' => time(),
'token' => $token,
'type' => 'sync'
);
$requestBody = array(
'requestId' => '00',
'deviceType' => '0',
'invoiceTypeCode' => '0',
'machineNo' => '00',
'sellerTaxNo' => '0',
'apiName' => 'baiwang.tax.monitor.query',
'taxNo' => '0',
'methodCode' => '02'
);
$body = json_encode($requestBody);
$signString = signTopRequest($textParams, $appSecret, $body);
echo $signString;
function signTopRequest($params, $secret, $body) {
ksort($params);
$query = $secret;
foreach ($params as $key => $value) {
if (!isNull($key) && !isNull($value)) {
$query .= $key . $value;
}
}
$body = str_replace(array("\n", "\t", "\r"), '', $body);
$query .= $body . $secret;
$sign = strtoupper(md5($query));
return $sign;
}
function isNull($str) {
return ($str == null || $str == '');
}
?>
文档如下:
对拼接后的字符串进行加密
定义字符串 query 为拼接后的字符串
String query =
“b65025d0-19d2-4841-88f4-ff4439b8da58appKey10000005formatjson
methodbaiwang.input.collecttimestamp1517995027449token42397f1f-
2cc8-4c0e-a0a4-23d9d1d3bac7typesyncversion3.0{“taxCheck”:“0”,
“version”:“1.0”,“invoiceCode”:“1100171320”,“invoiceNu 05-21”,
“checkCode”:“349249”}b65025d0-19d2-4841-88f4-ff4439b8da58”;
把拼装好的字符串采用 utf-8 编码,并转为二进制数组使用 MD5 进行计算,
获取二进制字节数组(产生出一个 128 位(16 字节)的散列值) 如:
md5(secret+bar2foo1foo_bar3foobar4+body+secret)。
bytes = md5.digest(query.toString().getBytes(“UTF-8”));
将摘要得到的字节流结果使用十六进制表示,如:
hex(“helloworld”.getBytes(“utf-8”)) = “68656C6C6F776F726C64”
转换后的十六进制就是 sign 签名值:
7102B2C9F135FA3B22DD47286B6892B4
说明:MD5 是 128 位长度的摘要算法,用 16 进制表示,一个十六进制的
字符能表示 4 个位,所以签名后的字符串长度固定为 32 个十六进制字符