UNPKG

tencentcloud-sdk-nodejs-intl-en

Version:
125 lines (108 loc) 4.31 kB
const TencentCloudSDKHttpException = require("./exception/tencent_cloud_sdk_exception"); const crypto = require('crypto'); const { URL } = require('url') /** * @inner */ class Sign { static sign(secretKey, signStr, signMethod) { let signMethodMap = { HmacSHA1: "sha1", HmacSHA256: "sha256" }; if (!signMethodMap.hasOwnProperty(signMethod)) { throw new TencentCloudSDKHttpException("signMethod invalid, signMethod only support (HmacSHA1, HmacSHA256)"); } let 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(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 (let 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 : JSON.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}` } } 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}` } module.exports = Sign;