Я пытаюсь реализовать подпись AWS V4 в C, но я не могу вычислить хеш в строке для подписи. В тестовом примере здесь есть:

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

Производства

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

Но по какой-то причине моя реализация отбрасывает последние несколько символов последнего элемента, и я получаю:

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

Я просто использую пример расчета HMAC_SHA256 из https://stackoverflow.com/a/29862424/993874, Я не вижу, что мне не хватает. Для других расчетов (например, для выполнения запросов на мои собственные данные AWS и т. Д.) Я также вижу, что некоторые из выходных данных hmac не имеют длины 32 символа.

Может ли кто-нибудь помочь решить эту проблему (а также подтвердить, нужно ли мне преобразовывать все массивы символов в шестнадцатеричные строки для запросов 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;                                                                                                       
}         
0
radpotato 23 Окт 2018 в 13:15

2 ответа

Лучший ответ

Ваш цикл в PrintHex до strlen(toPrint). Это байтовый массив, а не строка, поэтому использовать strlen () нельзя. Цикл должен увеличиться до 32.

0
TheGreatContini 23 Окт 2018 в 10:32

Вы не можете использовать 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);

    }

Выход:

kSecret : 41575334774a616c725855746e46454d492f4b374d44454e472b62507852666943594558414d504c454b4559
kDate   : 969fbb94feb542b71ede6f87fe4d5fa29c789342b0f407474670f0c2489e0a0d
kRegion : 69daa0209cd9c5ff5c8ced464a696fd4252e981430b10e3d3fd8e2f197d7a70c
kService        : f72cfd46f26bc4643f06a11eabb6c0ba18780c19a8da0c31ace671265e3c87fa
kSigning        : f4780e2d9f65fa895f9c67b32ce1baf0b0d8a43505a000a1a9e090d414db404d
2
kiran Biradar 23 Окт 2018 в 10:56
52946556