tencentcloud-sdk-nodejs-common
Version:
113 lines (112 loc) • 4.55 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const tencent_cloud_sdk_exception_1 = tslib_1.__importDefault(require("./exception/tencent_cloud_sdk_exception"));
const crypto = tslib_1.__importStar(require("crypto"));
const url_1 = require("url");
const json_bigint_1 = tslib_1.__importDefault(require("json-bigint"));
const JSONbigNative = json_bigint_1.default({ useNativeBigInt: true });
/**
* @inner
*/
class Sign {
static sign(secretKey, signStr, signMethod) {
const signMethodMap = {
HmacSHA1: "sha1",
HmacSHA256: "sha256",
};
if (!signMethodMap.hasOwnProperty(signMethod)) {
throw new tencent_cloud_sdk_exception_1.default("signMethod invalid, signMethod only support (HmacSHA1, HmacSHA256)");
}
const hmac = crypto.createHmac(signMethodMap[signMethod], secretKey || "");
return hmac.update(Buffer.from(signStr, "utf8")).digest("base64");
}
static sign3({ method = "POST", url = "", payload, timestamp, service, secretId, secretKey, multipart, boundary, headers: configHeaders = {}, }) {
const urlObj = new url_1.URL(url);
const contentType = configHeaders["Content-Type"];
// 通用头部
let headers = "";
let signedHeaders = "";
if (method === "GET") {
signedHeaders = "content-type";
headers = `content-type:${contentType}\n`;
}
else if (method === "POST") {
signedHeaders = "content-type";
if (multipart) {
headers = `content-type:multipart/form-data; boundary=${boundary}\n`;
}
else {
headers = `content-type:${contentType}\n`;
}
}
headers += `host:${urlObj.hostname}\n`;
signedHeaders += ";host";
const path = urlObj.pathname;
const querystring = urlObj.search.slice(1);
let payload_hash = "";
if (multipart) {
const hash = crypto.createHash("sha256");
hash.update(`--${boundary}`);
for (const key in payload) {
const content = payload[key];
if (Buffer.isBuffer(content)) {
hash.update(`\r\nContent-Disposition: form-data; name="${key}"\r\nContent-Type: application/octet-stream\r\n\r\n`);
hash.update(content);
hash.update("\r\n");
}
else if (typeof content === "string") {
hash.update(`\r\nContent-Disposition: form-data; name="${key}"\r\n\r\n`);
hash.update(`${content}\r\n`);
}
hash.update(`--${boundary}`);
}
hash.update(`--\r\n`);
payload_hash = hash.digest("hex");
}
else {
const hashMessage = Buffer.isBuffer(payload) ? payload : JSONbigNative.stringify(payload);
payload_hash = payload ? getHash(hashMessage) : getHash("");
}
const canonicalRequest = method +
"\n" +
path +
"\n" +
querystring +
"\n" +
headers +
"\n" +
signedHeaders +
"\n" +
payload_hash;
const date = getDate(timestamp);
const StringToSign = "TC3-HMAC-SHA256" +
"\n" +
timestamp +
"\n" +
`${date}/${service}/tc3_request` +
"\n" +
getHash(canonicalRequest);
const kDate = sha256(date, "TC3" + secretKey);
const kService = sha256(service, kDate);
const kSigning = sha256("tc3_request", kService);
const signature = sha256(StringToSign, kSigning, "hex");
return `TC3-HMAC-SHA256 Credential=${secretId}/${date}/${service}/tc3_request, SignedHeaders=${signedHeaders}, Signature=${signature}`;
}
}
exports.default = Sign;
function sha256(message, secret = "", encoding) {
const hmac = crypto.createHmac("sha256", secret);
return hmac.update(message).digest(encoding);
}
function getHash(message, encoding = "hex") {
const hash = crypto.createHash("sha256");
return hash.update(message).digest(encoding);
}
function getDate(timestamp) {
const date = new Date(timestamp * 1000);
const year = date.getUTCFullYear();
const month = ("0" + (date.getUTCMonth() + 1)).slice(-2);
const day = ("0" + date.getUTCDate()).slice(-2);
return `${year}-${month}-${day}`;
}
;