最近由于乙方只有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));
}
最后修改:2024 年 11 月 20 日
如果觉得我的文章对你有用,请随意赞赏