Question

J'essaie de configurer un test de base du hachage HMAC-SHA-256, mais la configuration du moteur me pose problème. Idéalement, je souhaiterais configurer uniquement l'algorithme HMAC-SHA, mais je n'ai pas encore compris le cas général où charger tous les algorithmes fonctionne. Actuellement, je reçois des segfaults sur la ligne où je tente de définir les condensés par défaut.

De plus, je suis régulièrement un gars de Java, alors n'hésitez pas à signaler les erreurs éventuelles dans le code.

#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main() {
  unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b";
  unsigned char* data = (unsigned char*) "4869205468657265";
  unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7";
  unsigned char* result;
  HMAC_CTX* ctx;
  ENGINE* e;

  ENGINE_load_builtin_engines();
  ENGINE_register_all_complete();
  ENGINE_set_default_digests(e);

  HMAC_CTX_init(ctx);
  HMAC_Init_ex(ctx, key, 40, EVP_sha256(), e);
  result = HMAC(NULL, NULL, 40, data, 16, NULL, NULL);
  HMAC_CTX_cleanup(ctx);

  ENGINE_finish(e);
  ENGINE_free(e);

  if (strcmp((char*) result, (char*) expected) == 0) {
    printf("Test ok\n");
  } else {
    printf("Got %s instead of %s\n", result, expected);
  }
}

EDIT: le programme a maintenant évolué comme suit, mais je commets toujours une erreur de segmentation à HMAC_Init_ex :

unsigned char* key = (unsigned char*) "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b";
unsigned char* data = (unsigned char*) "4869205468657265";
unsigned char* expected = (unsigned char*) "b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7";
unsigned char* result;
unsigned int result_len = 64;
HMAC_CTX ctx;
ENGINE* e;

result = (unsigned char*) malloc(sizeof(char) * result_len);
e = (ENGINE*) ENGINE_new();

ENGINE_load_builtin_engines();
ENGINE_register_all_complete();
ENGINE_set_default_digests(e);

HMAC_CTX_init(&ctx);
HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), e); 
HMAC_Update(&ctx, data, 40);
HMAC_Final(&ctx, result, &result_len);
HMAC_CTX_cleanup(&ctx);

ENGINE_finish(e);
ENGINE_free(e);
Était-ce utile?

La solution

Le problème avec votre suggestion initiale est, comme l'a dit Martin, que vous deviez initialiser le moteur. Le problème avec votre code modifié était que vous étiez en train de faire ENGINE_new, ce qui vous donne un tout nouveau MOTEUR, que vous devez ensuite fournir avec des méthodes de chiffrement, des méthodes de résumé, etc. En fait, pour ce que vous voulez (et presque tout le monde veut), ignorer complètement tout ce qui est ENGINE est le bon choix.

Quelques problèmes subsidiaires:

  • vos chaînes étaient hexadécimales, mais vous aviez besoin d'un \ x par caractère pour obtenir cet octet hexadécimal à cette position dans la chaîne, ce qui, je suppose, était ce que vous souhaitiez.
  • vous vouliez hacher 40 octets à partir de "données", ce qui n’était pas si long (effet réel: vous finiriez par hacher en partie votre chaîne de résultat)
  • votre résultat attendu était (pour autant que je sache) incorrect
  • vous imprimeriez des caractères aléatoires sur le terminal, car la fonction HMAC produira 32 octets de données binaires aléatoires, et non des éléments imprimables.

Le code suivant compile, fonctionne et réussit le test. C'est un peu différent de l'exemple de code que vous avez trouvé (puisqu'il utilise toujours les fonctions individuelles HMAC_ * - utile si vous souhaitez effectuer votre hachage à l'aide de HMAC_Update):

#include <openssl/engine.h>
#include <openssl/hmac.h>
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>


int main(void)
{
        unsigned char* key = (unsigned char*) "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b";
        unsigned char* data = (unsigned char*) "\x48\x69\x20\x54\x68\x65\x72\x65";
        unsigned char* expected = (unsigned char*) "\x49\x2c\xe0\x20\xfe\x25\x34\xa5\x78\x9d\xc3\x84\x88\x06\xc7\x8f\x4f\x67\x11\x39\x7f\x08\xe7\xe7\xa1\x2c\xa5\xa4\x48\x3c\x8a\xa6";
        unsigned char* result;
        unsigned int result_len = 32;
        int i;
        HMAC_CTX ctx;

        result = (unsigned char*) malloc(sizeof(char) * result_len);

        ENGINE_load_builtin_engines();
        ENGINE_register_all_complete();

        HMAC_CTX_init(&ctx);
        HMAC_Init_ex(&ctx, key, 16, EVP_sha256(), NULL);
        HMAC_Update(&ctx, data, 8);
        HMAC_Final(&ctx, result, &result_len);
        HMAC_CTX_cleanup(&ctx);

        for (i=0; i!=result_len; i++)
        {
                if (expected[i]!=result[i])
                {
                        printf("Got %02X instead of %02X at byte %d!\n", result[i], expected[i], i);
                        break;
                }
        }
        if (i==result_len)
        {
                printf("Test ok!\n");
        }
        return 0;
}

Bien sûr, cela ne répond pas à votre question initiale sur la manière d’initialiser ENGINES, mais il n’ya vraiment pas de bonne réponse à cela sans avoir plus de contexte, lequel contexte s’avère ne pas être pertinent dans votre situation ...

Autres conseils

D'accord, il s'avère que vous n'avez pas besoin d'utiliser un moteur, mais j'aurais mal compris exactement comment ne pas utiliser un moteur explicite. J'ai également mal compris comment formater correctement les vecteurs de test. En fin de compte, j’ai jeté un œil sur hmactest.c, qui fait à peu près tout ce que je veux, mais je n’ai tout simplement pas compris le code.

La solution finale à ce que j'essayais de faire ressemble à ceci:

int main() {
  unsigned char* key = (unsigned char*) "Jefe";
  unsigned char* data = (unsigned char*) "what do ya want for nothing?";
  unsigned char* expected = (unsigned char*) "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843";
  unsigned char* result;
  unsigned int result_len = 32;
  int i;
  static char res_hexstring[32];

  result = HMAC(EVP_sha256(), key, 4, data, 28, NULL, NULL);
  for (i = 0; i < result_len; i++) {
    sprintf(&(res_hexstring[i * 2]), "%02x", result[i]);
  }

  if (strcmp((char*) res_hexstring, (char*) expected) == 0) {
    printf("Test ok, result length %d\n", result_len);
  } else {
    printf("Got %s instead of %s\n", res_hexstring, expected);
  }
}

Mais puisque je demandais quelque chose de complètement différent, je ne savais pas quoi faire de la question initiale. Suggestions?

Il semble que rien n'alloue de moteur. La première utilisation de e est une erreur de segmentation. Je pense que vous devez d'abord appeler ENGINE * ENGINE_new (void) .

(Notez que j'ai utilisé OpenSSL, mais je n'ai pas utilisé les fonctions ENGINE auparavant.)

Mise à jour : je ne suis pas vraiment satisfait de ma propre réponse (j'avais déjà dû me lancer dans le thé). Donc, mes notes supplémentaires sont:

  1. J'ai jeté un coup d'œil au (long) man page pour les fonctions ENGINE , et je ne suis pas sûr que le fait d'appeler ENGINE_new soit suffisant.

  2. Je n'ai pas remarqué que les appels aux fonctions HMAC_CTX _ * prenaient un pointeur non initialisé plutôt qu'un pointeur sur une structure allouée. HMAC_CTX_init essaiera d’écrire dans la mémoire pointée par son paramètre ctx , qui segfault. Vous devez déclarer et utiliser ctx comme ceci:

    HMAC_CTX ctx;
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, key, 40, EVP_sha256(), e);
    ...
    

    De cette manière, vous allouez la structure sur la pile, puis lui passez un pointeur.

  3. La fonction HMAC ne prend pas du tout un pointeur sur un CTX . Par conséquent, mis à part le stockage global ou local, je ne suis pas sûr Qu'est-ce que sa connexion au CTX est. Je pense que vous pouvez éviter cela en appelant HMAC_Update une ou plusieurs fois, suivi de HMAC_Final pour obtenir le résultat. Vous aurez besoin d’allouer de l’espace pour ce résultat. Ainsi, vous obtiendrez un résultat similaire à celui-ci:

    unsigned int len;
    HMAC_Final(&ctx, result, &len);
    
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top