C++ 中的 HMAC SHA256 (DynamoDB) [英] HMAC SHA256 in C++ (DynamoDB)

查看:158
本文介绍了C++ 中的 HMAC SHA256 (DynamoDB)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 REST Web API 连接到 DynamoDB,它要求我使用 HMAC-SHA256 生成签名.我有 SHA-256 工作,但我似乎无法让 HMAC 工作,这是 C++ 代码(使用 OpenSSL)

I'm trying to connect to DynamoDB through the REST Web API and it requires me to generate a signature using HMAC-SHA256. I've got SHA-256 working, but I cant seem to get HMAC working, here is the C++ code (using OpenSSL)

string hmac(string key, string msg)
{
    unsigned char hash[32];

    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, &key[0], key.length(), EVP_sha256(), NULL);
    HMAC_Update(&hmac, (unsigned char*) &msg[0], msg.length());
    unsigned int len = 32;
    HMAC_Final(&hmac, hash, &len);
    HMAC_CTX_cleanup(&hmac);

    stringstream ss;
    for (int i = 0; i < len; i++)
    {   
        ss << hex  <<  ( unsigned int )hash[i];
    }

    return ss.str();
}

这是对 hmac 的调用

Here is the call to hmac

    /*********************************************CALCULATE SIGNATURE****************************************************************/

string AWS4 = "AWS4" + secretKey;

string Kdate = hmac(AWS4.data(), dateStamp);
string Kregion = hmac(Kdate.data(), region);
string Kservice = hmac(Kregion.data(), service);
string signingkey = hmac(Kservice.data(), "aws4_request");

string signature = hmac(signingkey.data(), stringToSign);

string authoritzationHeader = algorithm + " Credential=" + accessKey + "/" + credential_scope + ", SignedHeaders=" + signedHeaders + ", Signature=" + signature;

这是我基于它的 Python 代码:

This is the Python code I'm basing it off:

def sign(key, msg):
    return hmac.new(key, msg.encode("utf-8"), hashlib.sha256).digest()

def getSignatureKey(key, date_stamp, regionName, serviceName):
    kDate    = sign(('AWS4' + key).encode('utf-8'), date_stamp)
    kRegion  = sign(kDate, regionName)
    kService = sign(kRegion, serviceName)
    kSigning = sign(kService, 'aws4_request')

    print 'Kdate: ' + kDate
    print 'Kregion: ' + kRegion 
    print 'Kservice: ' + kService

    return kSigning

给定相同的值,它们会产生不同的结果.谁能帮我解释这是为什么?谢谢.

Given the same values they produce a different result. Can anyone help me as to why this is? Thanks.

推荐答案

问题在于 DynamoDB 以两种不同的方式计算 hmac.第一个返回字符串表示,第二个返回十六进制表示

The issue is that DynamoDB calculates hmac in two different ways. The first returns a string representation and the second returns a hex representation

十六进制实现

string hmacHex(string key, string msg)
{
    unsigned char hash[32];

    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, &key[0], key.length(), EVP_sha256(), NULL);
    HMAC_Update(&hmac, (unsigned char*)&msg[0], msg.length());
    unsigned int len = 32;
    HMAC_Final(&hmac, hash, &len);
    HMAC_CTX_cleanup(&hmac);

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

    return (ss.str());
}

字符串实现

string hmac(string key, string msg)
{
    unsigned char hash[32];

    HMAC_CTX hmac;
    HMAC_CTX_init(&hmac);
    HMAC_Init_ex(&hmac, &key[0], key.length(), EVP_sha256(), NULL);
    HMAC_Update(&hmac, ( unsigned char* )&msg[0], msg.length());
    unsigned int len = 32;
    HMAC_Final(&hmac, hash, &len);
    HMAC_CTX_cleanup(&hmac);

    std::stringstream ss;
    ss << std::setfill('0');
    for (int i = 0; i < len; i++)
    {
        ss  << hash[i];
    }

    return (ss.str());
}

亚马逊对所有日期、地区、服务和签名密钥使用十六进制实现.字符串实现只用于签名

Amazon uses the hex implementation for all date, region, service and signing key. The string implementation is only used for the signature

这篇关于C++ 中的 HMAC SHA256 (DynamoDB)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆