All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ms.tools.api.tencent.factory.ApiSignV3 Maven / Gradle / Ivy

There is a newer version: 1.2.2
Show newest version
/*
 * @MS 2022-12-13
 * Copyright (c) 2001-2023 萌森
 * 保留所有权利
 * 本软件为萌森工作室所有及包含机密信息,须遵守其相关许可证条款进行使用。
 * Copyright (c) 2001-2023 Meng Sen
 * All rights reserved
 * This software is owned by Mengsen Studio and contains confidential information, and must be used in accordance with its relevant license terms.
 * Website:https://qyg2297248353.top
 */

package com.ms.tools.api.tencent.factory;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import java.util.logging.Logger;

/**
 * 腾讯云签名
 *
 * @author qyg2297248353
 */
public class ApiSignV3 {
    private static final Logger log = Logger.getLogger(ApiSignV3.class.getName());

    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 {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] d = md.digest(s.getBytes(StandardCharsets.UTF_8));
        return DatatypeConverter.printHexBinary(d).toLowerCase();
    }

    public static String signV3(String secretId, String secretKey, String timestamp, String payload) {
        try {
            final String service = "sms";
            String host = TencentCloudApiConfig.Host.MAIN_SMS.getHost();
            final String algorithm = "TC3-HMAC-SHA256";

            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            // 注意时区,否则容易出错
            sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
            String date = sdf.format(new Date(Long.parseLong(timestamp + "000")));

            // ************* 步骤 1:拼接规范请求串 *************
            final String httpRequestMethod = "POST";
            final String canonicalUri = "/";
            final String canonicalQueryString = "";
            String canonicalHeaders = "content-type:application/json; charset=utf-8\n" + "host:" + host + "\n";
            final String signedHeaders = "content-type;host";

            String hashedRequestPayload = sha256Hex(payload);
            String canonicalRequest = httpRequestMethod + "\n" + canonicalUri + "\n" + canonicalQueryString + "\n"
                    + canonicalHeaders + "\n" + signedHeaders + "\n" + hashedRequestPayload;

            // ************* 步骤 2:签名字段 *************
            String credentialScope = date + "/" + service + "/" + "tc3_request";
            String hashedCanonicalRequest = sha256Hex(canonicalRequest);
            String stringToSign = algorithm + "\n" + timestamp + "\n" + credentialScope + "\n" + hashedCanonicalRequest;

            // ************* 步骤 3:计算签名 *************
            byte[] secretDate = hmac256(("TC3" + secretKey).getBytes(StandardCharsets.UTF_8), date);
            byte[] secretService = hmac256(secretDate, service);
            byte[] secretSigning = hmac256(secretService, "tc3_request");
            String signature = DatatypeConverter.printHexBinary(hmac256(secretSigning, stringToSign)).toLowerCase();

            // ************* 步骤 4:拼接 Authorization *************
            return algorithm + " " + "Credential=" + secretId + "/" + credentialScope + ", "
                    + "SignedHeaders=" + signedHeaders + ", " + "Signature=" + signature;
        } catch (Exception e) {
            log.warning(e.getMessage());
            return "";
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy