最近由于乙方只有java的接口demo,而我方是用的php环境,所以需要将java版的接口demo改成php版
一、java的demo代码
// 主程序
public static void demo1() {
String content = "";
Base64 base64 = new Base64();
String base64Sign = base64.encodeToString(content.getBytes());
System.out.println("base64签名>>>> " + base64Sign);
Map<String, String> queryMap = new HashMap<String, String>();
queryMap.put("content", base64Sign);
queryMap.put("appid", appid);
String timeStamp = getTimeStamp();
queryMap.put("serviceid", "sss");
queryMap.put("source", "xxx");
queryMap.put("signkey", "appid,signkey,timestamp,content,serviceid,source");
String signature = SignUtil.sign(appsecret, queryMap);
System.out.println("签名结果>>>> " + signature);
}
// SignUtil类
import java.util.Map;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
/**
* 签名工具
*/
public class SignUtil {
public static final String HMAC_SHA256 = "HmacSHA256";
public static final String ENCODING = "UTF-8";
public static final String LF = "\n";
public static final String SPE1 = ",";
public static final String SPE2 = ":";
public static final String SPE3 = "&";
public static final String SPE4 = "=";
public static final String SPE5 = "?";
public static String sign(String secret, Map<String, String> querys) {
try {
Mac hmacSha256 = Mac.getInstance(HMAC_SHA256);
byte[] keyBytes = secret.getBytes(ENCODING);
hmacSha256.init(new SecretKeySpec(keyBytes, 0, keyBytes.length, HMAC_SHA256));
return new String(Base64.encodeBase64(hmacSha256.doFinal(buildResource(querys).getBytes(ENCODING))),
ENCODING);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String buildResource(Map<String, String> querys) {
StringBuilder sb = new StringBuilder();
Map<String, String> sortMap = new TreeMap<String, String>();
if (null != querys) {
for (Map.Entry<String, String> query : querys.entrySet()) {
if (!StringUtils.isBlank(query.getKey())) {
sortMap.put(query.getKey(), query.getValue());
}
}
}
StringBuilder sbParam = new StringBuilder();
for (Map.Entry<String, String> item : sortMap.entrySet()) {
if (!StringUtils.isBlank(item.getKey())) {
if (0 < sbParam.length()) {
sbParam.append(SPE3);
}
sbParam.append(item.getKey());
if (!StringUtils.isBlank(item.getValue())) {
sbParam.append(SPE4).append(item.getValue());
}
}
}
if (0 < sbParam.length()) {
sb.append(SPE5);
sb.append(sbParam);
}
return sb.toString();
}
}
二、转换后的php代码
$content = "";
$base64Sign = base64_encode($content);
//echo 'base64加密>>>> '.$base64Sign;
$queryMap = [];
$queryMap['content'] = $base64Sign;
$queryMap['appid'] = $this->appid;
// 获取毫秒级的时间格式化字符串
$queryMap['timestamp'] = get_msec_to_mescdate(get_msec_time());
$queryMap['serviceid'] = 'SSS';
$queryMap['source'] = 'XXX';
$queryMap['signkey'] = "appid,signkey,timestamp,content,serviceid,source";
$signature = $this->getSignature($queryMap,$this->appsecret);
//echo '报文签名>>>> '.$signature;
public function getSignature($params, $secret)
{
$str = '?'; // 待签名字符串
// 先将参数以其参数名的字典序升序进行排序
ksort($params);
// 遍历排序后的参数数组中的每一个key/value对
foreach ($params as $k => $v) {
// 为key/value对生成一个key=value格式的字符串,并拼接到待签名字符串后面
$str .= "$k=$v&";
}
// 等同于java调用signUtil工具类的buildResource方法得到的字符串
$buildResource = trim($str,'&');
// 将字符串加密后生成签名
return base64_encode(hash_hmac('sha256', $buildResource, $secret, true));
}