Domanda

Sto cercando di impostare un test di base dell'hash HMAC-SHA-256 ma sto riscontrando problemi con la configurazione del motore. Idealmente, vorrei impostare solo l'algoritmo HMAC-SHA, ma finora non ho nemmeno ottenuto il caso generale in cui caricare tutti gli algoritmi per funzionare. Attualmente sto ricevendo segfaults nella riga in cui provo a impostare i digest predefiniti.

Inoltre, sono regolarmente un ragazzo Java, quindi non esitate a segnalare eventuali errori nel codice.

#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: il programma si è ora evoluto come segue, ma sto ancora segfault su 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);
È stato utile?

Soluzione

Il problema con il tuo suggerimento originale è, come ha detto Martin, che devi inizializzare il MOTORE. Il problema con il tuo codice modificato era che stavi facendo ENGINE_new, che ti sta offrendo un ENGINE completamente nuovo, che dovrai quindi fornire con metodi di cifratura, metodi di digest, ecc. In effetti, per quello che vuoi (e cosa quasi tutti lo vogliono), ignorare completamente tutte le cose di ENGINE è la scelta giusta.

Alcuni problemi sussidiari:

  • le tue stringhe erano esadecimali, ma avevi bisogno di un \ x per carattere per ottenere effettivamente quel byte esadecimale in quella posizione nella stringa, che sospetto fosse quello che volevi.
  • stavi tentando di eseguire l'hashing di 40 byte da " dati " ;, che non era poi così lungo (effetto reale: finiresti per eseguire l'hashing parziale della stringa dei risultati)
  • il risultato atteso è stato (per quanto posso dire) errato
  • dovresti stampare caratteri casuali sul terminale, poiché la funzione HMAC produrrà 32 byte di dati binari casuali, non roba stampabile.

Il seguente codice compila, funziona e supera il test. È un po 'diverso dal codice di esempio che hai trovato (dal momento che utilizza ancora le singole funzioni HMAC_ * - utile se vuoi fare il tuo hashing bit per bit usando 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;
}

Ovviamente, non risponde alla tua domanda originale su come inizializzare ENGINEs, ma in realtà non esiste una risposta giusta a ciò senza avere più contesto, quale contesto risulta non essere rilevante nella tua situazione ...

Altri suggerimenti

Okay, risulta che non devi usare un motore ma ho capito male come non usare un motore esplicito. Ho anche frainteso come formattare correttamente i vettori di test. Alla fine ho guardato hmactest.c che praticamente fa tutto ciò che voglio fare, semplicemente non ho capito il codice.

La soluzione finale a quello che stavo cercando di fare è simile a questa:

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);
  }
}

Ma dal momento che stavo chiedendo qualcosa di completamente diverso, non sono sicuro di cosa fare con la domanda originale. Suggerimenti?

Sembra che nulla stia allocando un motore, quindi il primo utilizzo di e è segfaulting. Penso che prima devi chiamare ENGINE * ENGINE_new (void) .

(Nota che ho usato OpenSSL, ma non ho mai usato le funzioni ENGINE .)

Aggiorna : non sono molto contento della mia risposta (prima ho dovuto precipitarmi per un tè). Quindi le mie ulteriori note sono:

  1. Ho dato un'occhiata al (lungo) pagina per le funzioni ENGINE e non sono del tutto sicuro che chiamare ENGINE_new sia sufficiente.

  2. Non ho notato che le chiamate alle funzioni HMAC_CTX_ * stavano prendendo un puntatore non inizializzato, piuttosto che un puntatore a una struttura allocata. HMAC_CTX_init proverà a scrivere nella memoria indicata dal parametro ctx , che segfault. Devi dichiarare e utilizzare ctx in questo modo:

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

    In questo modo stai allocando la struttura nello stack e quindi passando un puntatore ad essa.

  3. La funzione HMAC non punta affatto a un CTX , quindi a parte l'archiviazione globale o thread-local, non sono sicuro cos'è la connessione al CTX . Penso che puoi aggirarlo chiamando HMAC_Update una o più volte, seguito da HMAC_Final per ottenere il risultato. Dovresti allocare spazio per quel risultato, quindi qualcosa come il seguente funzionerebbe per questo:

    unsigned int len;
    HMAC_Final(&ctx, result, &len);
    
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top