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

相关推荐
小糖学代码11 小时前
LLM系列:1.python入门:3.布尔型对象
linux·开发语言·python
shizhan_cloud11 小时前
Shell 函数的知识与实践
linux·运维
Deng87234734811 小时前
代码语法检查工具
linux·服务器·windows
霍夫曼13 小时前
UTC时间与本地时间转换问题
java·linux·服务器·前端·javascript
月熊14 小时前
在root无法通过登录界面进去时,通过原本的普通用户qiujian如何把它修改为自己指定的用户名
linux·运维·服务器
大江东去浪淘尽千古风流人物14 小时前
【DSP】向量化操作的误差来源分析及其经典解决方案
linux·运维·人工智能·算法·vr·dsp开发·mr
赖small强15 小时前
【Linux驱动开发】NOR Flash 技术原理与 Linux 系统应用全解析
linux·驱动开发·nor flash·芯片内执行
IT运维爱好者16 小时前
【Linux】LVM理论介绍、实战操作
linux·磁盘扩容·lvm
LEEE@FPGA16 小时前
ZYNQ MPSOC linux hello world
linux·运维·服务器
郝学胜-神的一滴16 小时前
Linux定时器编程:深入理解setitimer函数
linux·服务器·开发语言·c++·程序人生