forked from Trustie/forgeplus
54 lines
1.4 KiB
Ruby
54 lines
1.4 KiB
Ruby
require 'openssl'
|
|
require 'base64'
|
|
require 'json'
|
|
require 'uri'
|
|
require 'time'
|
|
|
|
class Huawei::Signer
|
|
def initialize(ak, sk)
|
|
@ak = ak
|
|
@sk = sk
|
|
end
|
|
|
|
def sign_request(method, url, headers = {}, body = "")
|
|
uri = URI.parse(url)
|
|
host = uri.host
|
|
path = uri.path.empty? ? "/" : uri.path
|
|
query = uri.query ? "?" + uri.query : ""
|
|
|
|
# 时间戳
|
|
x_sdk_date = Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
|
|
|
|
# Step 1: CanonicalRequest
|
|
canonical_headers = "host:#{host}\n" \
|
|
"x-sdk-date:#{x_sdk_date}\n"
|
|
|
|
signed_headers = "host;x-sdk-date"
|
|
|
|
hashed_payload = Digest::SHA256.hexdigest(body)
|
|
|
|
canonical_request = "#{method}\n#{path}\n#{query}\n#{canonical_headers}\n#{signed_headers}\n#{hashed_payload}"
|
|
|
|
# Step 2: StringToSign
|
|
hashed_canonical = Digest::SHA256.hexdigest(canonical_request)
|
|
string_to_sign = "SDK-HMAC-SHA256\n#{x_sdk_date}\n#{hashed_canonical}"
|
|
|
|
# Step 3: 计算签名
|
|
signature = OpenSSL::HMAC.hexdigest("SHA256", @sk, string_to_sign)
|
|
|
|
# Step 4: 生成 Authorization
|
|
authorization = "SDK-HMAC-SHA256 Access=#{@ak}, SignedHeaders=#{signed_headers}, Signature=#{signature}"
|
|
|
|
# 合并 headers
|
|
signed_headers_hash = {
|
|
"Authorization" => authorization,
|
|
"X-Sdk-Date" => x_sdk_date,
|
|
"Host" => host,
|
|
"Content-Type" => "application/json"
|
|
}
|
|
|
|
headers.merge!(signed_headers_hash)
|
|
headers
|
|
end
|
|
end
|