aliyun Rest ful api V3版本身份验证构造

aliyun Rest ful api V3版本身份验证构造

参考官网https://help.aliyun.com/zh/sdk/product-overview/v3-request-structure-and-signature?spm=a2c4g.11186623.0.0.787951e7lHcjZb
构造代码 :使用GET请求进行构造,算法使用sha256 使用postman进行验证

代码如下,linux环境运行,先安装openssl库:

cpp 复制代码
#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstring>
#include <random>
#include <chrono>
#include <cctype>
#include <iomanip>
#include <openssl/hmac.h>
#include <openssl/sha.h>
// HMAC-SHA256 calculation using OpenSSL library
//build,在Linux下编译 :  g++ -o a.out awsSignature.cpp -std=c++11 -lssl -lcrypto
std::string HMAC_SHA256(const std::string& key, const std::string& data) {
    unsigned char result[EVP_MAX_MD_SIZE];
    unsigned int result_len;

    HMAC(EVP_sha256(), key.c_str(), key.length(),
         reinterpret_cast<const unsigned char*>(data.c_str()), data.length(),
         result, &result_len);

    std::stringstream ss;
    for (unsigned int i = 0; i < result_len; i++) {
        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(result[i]);
    }

    return ss.str();
}
// AWS Signature Version 4 calculation
std::string CalculateAWSV4Signature(const std::string& secretAccessKey, const std::string& region,
                                    const std::string& service, const std::string& timestamp,
                                    const std::string& payloadHash, const std::string& canonicalRequest) {
    // Step 1: Derive signing key
    std::string kDate = HMAC_SHA256("AWS4" + secretAccessKey, timestamp.substr(0, 8));
    std::string kRegion = HMAC_SHA256(kDate, region);
    std::string kService = HMAC_SHA256(kRegion, service);
    std::string kSigning = HMAC_SHA256(kService, "aws4_request");

    // Step 2: Calculate signature
    std::string stringToSign = "AWS4-HMAC-SHA256\n" + timestamp + "\n" + timestamp.substr(0, 8) +
                               "/" + region + "/" + service + "/aws4_request\n" + HMAC_SHA256(kSigning, canonicalRequest + "\n" + payloadHash);
    std::string signature = HMAC_SHA256(kSigning, stringToSign);

    return signature;
}

std::string calculateHash(const std::string& data) {
    unsigned char hash[SHA256_DIGEST_LENGTH];

    SHA256_CTX sha256;
    SHA256_Init(&sha256);
    SHA256_Update(&sha256, data.c_str(), data.length());
    SHA256_Final(hash, &sha256);

    std::stringstream ss;
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
        ss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(hash[i]);
    }
    return ss.str();
}
std::string CanonicalizeRequest(const std::string& HTTPMethod, const std::string& CanonicalUri, const std::string& CanonicalQueryString, const std::string& CanonicalHeaders, const std::string& SignedHeaders, const std::string& payload)
{
		std::string canonicalize_string= HTTPMethod + "\n" +
		"/"+CanonicalUri + "\n" +
		CanonicalQueryString + "\n" +
		CanonicalHeaders + "\n" +
		SignedHeaders + "\n" +
		payload;
		return canonicalize_string;
}
std::string generateSignatureNonce() {
    // 使用 std::random_device 获取真正的随机数种子
    std::random_device rd;

    // 使用 std::mt19937 作为伪随机数生成器引擎
    std::mt19937 gen(rd());

    // 使用 std::uniform_int_distribution 来生成范围内的随机数
    std::uniform_int_distribution<> dis(0, 999999);

    // 生成随机数
    int nonceValue = dis(gen);

    // 将随机数转换为字符串
    std::ostringstream oss;
    oss << nonceValue;

    return oss.str();
}
std::string GetDate(int t){
	std::chrono::system_clock::time_point now_time = std::chrono::system_clock::now();
	std::time_t now_t = std::chrono::system_clock::to_time_t(now_time);
    std::tm gm_time = *std::gmtime(&now_t);
    char buf[128];
	if(t==1)
		std::strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", &gm_time);
	else
	{
		std::strftime(buf, sizeof(buf), "%FT%TZ", &gm_time);
	}
		
	std::string time(buf);
	return time;
}

std::string UrlEncode(std::string& url){
	std::ostringstream encoded;
    encoded << std::hex << std::uppercase << std::setfill('0');

    for (char ch : url) {
        if (std::isalnum(ch) || ch == '-' || ch == '_' || ch == '.' || ch == '~') {
            // 字母数字字符和"- _ ."波浪符号保持不变
            encoded << ch;
        } else {
            // 其他字符进行百分号编码
            encoded << '%' << std::setw(2) << static_cast<int>(static_cast<unsigned char>(ch));
        }
    }

    return encoded.str();
}
int main() {
    // AWS credentials and request details
    std::string accessKeyId = "你们密钥id";
    std::string secretAccessKey = "你的密钥";
    std::string region = "cn-shanghai";
    std::string param = "RegionId";
	std::string version="2014-05-26";
    std::string timestamp =GetDate(2);
	std::cout<<"timestamp: "<<timestamp<<std::endl;
    std::string canonicalRequest = "";
	std::string GMTime=GetDate(1);//GMT=1
	std::cout<<"GMTime"<<GMTime<<std::endl;
	//规范化请求构建参数
	std::string signature_nonce=generateSignatureNonce();
	std::cout<<signature_nonce<<std::endl;
	std::string HTTPRequestMethod="GET";
	std::string CanonicalURI ="";
	std::string CanonicalQueryString=UrlEncode(param)+"="+UrlEncode(region);//升序 url编码
	std::string CanonicalHeaders="host:ecs.cn-shanghai.aliyuncs.com\nx-acs-action:DescribeInstances\nx-acs-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\nx-acs-date:"+timestamp+"\nx-acs-signature-nonce:"+signature_nonce+"\nx-acs-version:"+version+"\n";
	std::string SignedHeaders="host;x-acs-action;x-acs-content-sha256;x-acs-date;x-acs-signature-nonce;x-acs-version";
	std::string HashedRequestPayload="e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
	//获取规范化请求值
	std::string CanonicalRequestString=CanonicalizeRequest(HTTPRequestMethod,CanonicalURI,CanonicalQueryString,CanonicalHeaders,SignedHeaders,HashedRequestPayload);
	std::cout<<CanonicalRequestString<<std::endl;
	//计算规范化请求的hash值
	std::string hashCanonicalRequest=calculateHash(CanonicalRequestString);
	std::string StringToSign="ACS3-HMAC-SHA256\n"+hashCanonicalRequest;

	//. 计算signature
	std::string signature = HMAC_SHA256(secretAccessKey,StringToSign);
    std::cout << "signature: " << signature << std::endl;
    return 0;
}

然后打开postman:

将算出来的信息在这里赋值,包含唯一随机数、时间、还有signature

然后 over

相关推荐
Doro再努力1 小时前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
wypywyp1 小时前
8. ubuntu 虚拟机 linux 服务器 TCP/IP 概念辨析
linux·服务器·ubuntu
Doro再努力2 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
senijusene2 小时前
Linux软件编程:IO编程,标准IO(1)
linux·运维·服务器
忧郁的橙子.2 小时前
02-本地部署Ollama、Python
linux·运维·服务器
醇氧2 小时前
【linux】查看发行版信息
linux·运维·服务器
No8g攻城狮3 小时前
【Linux】Windows11 安装 WSL2 并运行 Ubuntu 22.04 详细操作步骤
linux·运维·ubuntu
XiaoFan0123 小时前
免密批量抓取日志并集中输出
java·linux·服务器
souyuanzhanvip3 小时前
ServerBox v1.0.1316 跨平台 Linux 服务器管理工具
linux·运维·服务器
HalvmånEver4 小时前
Linux:线程互斥
java·linux·运维