!50 腾讯元短信签名修改

Merge pull request !50 from Richard/dev-2.x
This commit is contained in:
Richard 2023-05-25 13:55:06 +00:00 committed by Gitee
commit 9d4eceeda0
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 25 additions and 23 deletions

View File

@ -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);

View File

@ -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;
}
/**