hmac sha256输出长度

时间:2018-10-23 10:15:29

标签: c amazon-web-services encryption

我正在尝试在C中实现AWS V4 signature,但未能计算要签名的字符串中的哈希。测试示例here具有:

key = 'wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY'
dateStamp = '20120215'
regionName = 'us-east-1'
serviceName = 'iam'

生产

kSecret  = '41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559'
kDate    = '969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d'
kRegion  = '69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c'
kService = 'f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa'
kSigning = 'f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d'

但是,由于某种原因,我的实现删除了final元素的最后几个字符,我得到了:

kSecret : 41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559
kDate   : 969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d
kRegion : 69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c
kService    : f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa
kSigning    : f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a0

我只是使用来自https://stackoverflow.com/a/29862424/993874的HMAC_SHA256计算示例,我看不到我所缺少的内容。对于其他计算(即对我自己的AWS数据执行请求的计算等),我还看到某些hmac输出的长度不是32个字符。

任何人都可以帮助解决这个问题(并确认是否需要将所有char数组转换为针对AWS请求的十六进制字符串)?

示例代码:

#include <stdio.h>                                                                                                    
#include <string.h>                                                                                                   

#include <openssl/hmac.h> 

void printHex(const char* preface, const char* toPrint) {                                                             

      printf("%s\t: ", preface);                                                                                      
      for(size_t i = 0; i < strlen(toPrint); i++) {                                                                   
            printf("%02x", toPrint[i] & 0xff);                                                                        
      }                                                                                                               
      printf("\n");                                                                                                   
}                                                                                                                     


void hmac_sha256(const unsigned char* key,                                                                            
                 const unsigned char* text,                                                                           
                 unsigned char* result) {                                                                             

      unsigned int resultLen;                                                                                         

      HMAC(EVP_sha256(), key, strlen(key), text, strlen(text), result, &resultLen);                                   

}                                                                                                                     


void amazonV4Sign(const unsigned char* accessSecret,                                                                  
                  const unsigned char* amzDate,                                                                       
                  const unsigned char* region,                                                                        
                  const unsigned char* service) {                                                                     

      unsigned char kDate[BUFSIZ];                                                                                    
      unsigned char kRegion[BUFSIZ];                                                                                  
      unsigned char kService[BUFSIZ];                                                                                 
      unsigned char kSigning[BUFSIZ];                                                                                 

      unsigned char kSecret[BUFSIZ];                                                                                  
      sprintf(kSecret, "AWS4%s", accessSecret);                                                                       

      unsigned char request[BUFSIZ];                                                                                  
      sprintf(request, "aws4_request");                                                                               

      hmac_sha256(kSecret, amzDate, kDate);                                                                           
      hmac_sha256(kDate, region, kRegion);                                                                            
      hmac_sha256(kRegion, service, kService);                                                                        
      hmac_sha256(kService, request, kSigning);                                                                       

      printHex("kSecret", kSecret);                                                                                   
      printHex("kDate", kDate);                                                                                       
      printHex("kRegion", kRegion);                                                                                   
      printHex("kService", kService);                                                                                 
      printHex("kSigning", kSigning);                                                                                 

}                                                                                                                     


int main(int argc, char* argv[]) {                                                                                    

      unsigned char* key = "wJalrXUtnFEMI/K7MDENG+bPxRfiCYEXAMPLEKEY";                                                
      unsigned char* dateStamp = "20120215";                                                                          
      unsigned char* regionName = "us-east-1";                                                                        
      unsigned char* serviceName = "iam";                                                                             

      amazonV4Sign(key, dateStamp, regionName, serviceName);                                                          

      return 0;                                                                                                       
}         

2 个答案:

答案 0 :(得分:1)

您不能使用def applyConditionals[T](toApply: (() => Boolean, T => T)*) = toApply .foldLeft(a) { case (a, (cond, oper)) if cond() => oper(a) case (a, _) => a } val result = applyConditionals[Int] ( (() => condition, _ * 2), (() => condition2, _ * 6), (() => condition3, _ * 8) ) 来打印strlen输出,因为字节数组可能包含HMAC个字节。

因此,您可以如下使用0返回的md_len来打印字节数组。

HMAC返回HMAC的长度,语法为。

md

因此使用unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, const unsigned char *d, int n, unsigned char *md, unsigned int *md_len); 打印数组。

md_len

输出:

void printHex(const char* preface, const char* toPrint, int len) {

          printf("%s\t: ", preface);
          for(size_t i = 0; i < len; i++) {
                printf("%02x", toPrint[i] & 0xff);
          }
          printf("\n");
    }


    int hmac_sha256(const unsigned char* key,
                     const unsigned char* text,
                     unsigned char* result) {

          unsigned int resultLen;

          HMAC(EVP_sha256(), key, strlen(key), text, strlen(text), result, &resultLen);
          printf("%d\n", resultLen);
          return resultLen;
    }


    void amazonV4Sign(const unsigned char* accessSecret,
                      const unsigned char* amzDate,
                      const unsigned char* region,
                      const unsigned char* service) {

          unsigned char kDate[EVP_MAX_MD_SIZE] = {0};
          unsigned char kRegion[EVP_MAX_MD_SIZE] = {0};
          unsigned char kService[EVP_MAX_MD_SIZE] = {0};
          unsigned char kSigning[EVP_MAX_MD_SIZE] = {0};

          unsigned char kSecret[BUFSIZ];
          sprintf(kSecret, "AWS4%s", accessSecret);

          printf("%s\n", kSecret);
          unsigned char request[BUFSIZ];
          sprintf(request, "aws4_request");

          int len = hmac_sha256(kSecret, amzDate, kDate);
          printHex("kSecret", kSecret,strlen(kSecret));
          printHex("kDate", kDate,len);
          len = hmac_sha256(kDate, region, kRegion);
          printHex("kRegion", kRegion,len);
          len = hmac_sha256(kRegion, service, kService);
          printHex("kService", kService,len);
          len = hmac_sha256(kService, request, kSigning);

          printHex("kSigning", kSigning,len);

    }

答案 1 :(得分:0)

您在PrintHex中的循环最多为const app = dialogflow({debug: true, clientId:'*.apps.googleusercontent.com'}); var firebase = require('firebase'); const {dialogflow} = require('actions-on-google'); const functions = require('firebase-functions'); app.intent('Default Welcome Intent',(conv) =>{ conv.ask(new SignIn('To get your account details')); }); app.intent('Get Signin', (conv, signin) => { if (signin.status === 'OK') { const payload = conv.user.profile.payload conv.ask(`I got your account details, ${payload.name}. What do you want to do next?`) } else { conv.ask(`I won't be able to save your data, but what do you want to do next?`) } }); 。它是一个字节数组,而不是字符串,因此您不能使用strlen()。循环最多需要32个。