mirror of
https://gitee.com/dromara/sms4j.git
synced 2025-12-06 17:08:40 +08:00
commit
9d4eceeda0
@ -2,6 +2,7 @@ package org.dromara.sms4j.tencent.service;
|
||||
|
||||
import cn.hutool.json.JSONArray;
|
||||
import cn.hutool.json.JSONObject;
|
||||
import com.jdcloud.sdk.utils.StringUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.api.AbstractSmsBlend;
|
||||
import org.dromara.sms4j.api.entity.SmsResponse;
|
||||
@ -97,10 +98,16 @@ public class TencentSmsImpl extends AbstractSmsBlend {
|
||||
.onSuccess(((data, req, res) -> {
|
||||
JSONObject jsonBody = res.get(JSONObject.class);
|
||||
JSONObject response = jsonBody.getJSONObject("Response");
|
||||
JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
|
||||
smsResponse.setBizId(sendStatusSet.getJSONObject(0).getStr("SerialNo"));
|
||||
smsResponse.setMessage(sendStatusSet.getJSONObject(0).getStr("Message"));
|
||||
smsResponse.setCode(sendStatusSet.getJSONObject(0).getStr("Code"));
|
||||
String error = response.getStr("Error");
|
||||
if (StringUtils.isNotBlank(error)){
|
||||
smsResponse.setErrorCode("500");
|
||||
smsResponse.setErrMessage(error);
|
||||
}else {
|
||||
JSONArray sendStatusSet = response.getJSONArray("SendStatusSet");
|
||||
smsResponse.setBizId(sendStatusSet.getJSONObject(0).getStr("SerialNo"));
|
||||
smsResponse.setMessage(sendStatusSet.getJSONObject(0).getStr("Message"));
|
||||
smsResponse.setCode(sendStatusSet.getJSONObject(0).getStr("Code"));
|
||||
}
|
||||
}))
|
||||
.onError((ex, req, res) -> {
|
||||
JSONObject jsonBody = res.get(JSONObject.class);
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
package org.dromara.sms4j.tencent.utils;
|
||||
|
||||
import cn.hutool.crypto.digest.HMac;
|
||||
import cn.hutool.crypto.digest.HmacAlgorithm;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.dromara.sms4j.tencent.config.TencentConfig;
|
||||
|
||||
import javax.crypto.Mac;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
@ -34,9 +34,11 @@ public class TencentUtils {
|
||||
private static final String CT_JSON = "application/json; charset=utf-8";
|
||||
|
||||
|
||||
private static byte[] hmac256(byte[] key, String msg) {
|
||||
HMac hMac = new HMac(HmacAlgorithm.HmacSHA256, key);
|
||||
return hMac.digest(msg.getBytes(StandardCharsets.UTF_8));
|
||||
private static byte[] hmac256(byte[] key, String msg) throws Exception {
|
||||
Mac mac = Mac.getInstance("HmacSHA256");
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(key, mac.getAlgorithm());
|
||||
mac.init(secretKeySpec);
|
||||
return mac.doFinal(msg.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
private static String sha256Hex(String s) throws Exception {
|
||||
@ -56,37 +58,30 @@ public class TencentUtils {
|
||||
*/
|
||||
public static String generateSignature(TencentConfig tencentConfig, String templateId, String[] messages, String[] phones,
|
||||
String timestamp) throws Exception {
|
||||
// ************* 步骤 1:拼接规范请求串 *************
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
|
||||
String date = sdf.format(new Date(Long.parseLong(timestamp + "000")));
|
||||
String canonicalUri = "/";
|
||||
String canonicalQueryString = "";
|
||||
String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + tencentConfig.getRequestUrl() + "\n";
|
||||
String canonicalHeaders = "content-type:application/json; charset=utf-8\nhost:" + tencentConfig.getRequestUrl() + "\n";
|
||||
String signedHeaders = "content-type;host";
|
||||
HashMap<String, Object> params = new HashMap<>();
|
||||
// 实际调用需要更新参数,这里仅作为演示签名验证通过的例子
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("PhoneNumberSet", phones);
|
||||
params.put("SmsSdkAppId", tencentConfig.getSdkAppId());
|
||||
params.put("SignName", tencentConfig.getSignature());
|
||||
params.put("TemplateId", templateId);
|
||||
params.put("TemplateParamSet", messages);
|
||||
String payload = JSONUtil.toJsonStr(params);
|
||||
String payload = JSON.toJSONString(params);
|
||||
String hashedRequestPayload = sha256Hex(payload);
|
||||
String canonicalRequest = HTTP_REQUEST_METHOD + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
|
||||
+ canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
|
||||
// ************* 步骤 2:拼接待签名字符串 *************
|
||||
String credentialScope = date + "/" + tencentConfig.getService() + "/" + "tc3_request";
|
||||
String canonicalRequest = HTTP_REQUEST_METHOD + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n" + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;
|
||||
String credentialScope = date + "/" + tencentConfig.getService() + "/tc3_request";
|
||||
String hashedCanonicalRequest = sha256Hex(canonicalRequest);
|
||||
String stringToSign = ALGORITHM + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;
|
||||
// ************* 步骤 3:计算签名 *************
|
||||
byte[] secretDate = hmac256(("TC3" + tencentConfig.getAccessKeySecret()).getBytes(StandardCharsets.UTF_8), date);
|
||||
byte[] secretService = hmac256(secretDate, tencentConfig.getService());
|
||||
byte[] secretSigning = hmac256(secretService, "tc3_request");
|
||||
String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();
|
||||
// ************* 步骤 4:拼接 Authorization *************
|
||||
return ALGORITHM + " " + "Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", "
|
||||
+ "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
|
||||
return ALGORITHM + " Credential=" + tencentConfig.getAccessKeyId() + "/" + credentialScope + ", SignedHeaders=" + signedHeaders + ", Signature=" + signature;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user