Usa la funzione crypt in C

Jinku Hu 12 ottobre 2023
  1. Utilizzare la funzione crypt per hash le passphrase per l’archiviazione
  2. Utilizzare rigide routine di gestione degli errori per garantire la corretta esecuzione delle funzioni crypt
Usa la funzione crypt in C

Questo articolo spiegherà diversi metodi su come utilizzare la funzione crypt in C.

Utilizzare la funzione crypt per hash le passphrase per l’archiviazione

crypt è in realtà una famiglia di quattro funzioni che forniscono i metodi di hashing della passphrase per l’archiviazione sul sistema o l’autenticazione. Si noti che queste funzioni non sono adatte per l’hashing crittografico generico poiché l’hashing della passphrase deve essere computazionalmente costoso rispetto a quelle generiche progettate per essere veloci e utilizzare meno potenza di elaborazione.

crypt accetta due argomenti char* passati come parametri qualificati const. Il primo argomento punta alla passphrase che deve essere sottoposta ad hashing, e il secondo è la stringa speciale chiamata setting, che dovrebbe essere generata usando la funzione crypt_gensalt. L’argomento setting fornisce più parametri per la funzione crypt come l’algoritmo di hashing da usare, il costo computazionale dell’hash (il valore più grande corrispondente a quello più costoso) e byte salt casuali. Si noti che i byte per salt devono essere crittograficamente casuali e possono essere ottenuti separatamente dalle utilità di generazione di numeri casuali specifiche del sistema. L’esempio seguente mostra il caso in cui il valore speciale - il puntatore nullo viene passato a crypt_gensalt come terzo parametro per indicare il recupero automatico di byte casuali.

Sono disponibili più algoritmi hash (dettagliatamente descritti in questa pagina) e vengono passati come identificatori di stringa univoci alla funzione crypt_gensalt. Una volta che crypt_gensalt restituisce la stringa setting, può essere passata alla funzione crypt insieme alla passphrase, e il valore di ritorno sarà la passphrase con hash che è testo ASCII stampabile. Usiamo l’algoritmo bcrypt identificato come stringa di prefisso "$2b$" nel codice di esempio successivo. Si noti che il secondo argomento della funzione crypt_gensalt specifica quanto dovrebbe essere costosa la generazione di hash con il valore 0 che specifica il livello predefinito dell’algoritmo dato. In questo caso, specifichiamo 15, che è il valore consigliato per l’algoritmo di hashing bcrypt.

#include "crypt.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

enum { MAX_LEN = 1024 };

int main(int argc, char *argv[]) {
  char *text, *encrypted, *salt;
  size_t len;
  long lnmax;

  text = malloc(MAX_LEN);

  printf("Input string to be hashed: ");
  if (fgets(text, MAX_LEN, stdin) == NULL) exit(EXIT_FAILURE);

  len = strlen(text);
  if (text[len - 1] == '\n') text[len - 1] = '\0';

  salt = crypt_gensalt("$2b$", 15, NULL, 0);
  encrypted = crypt(text, salt);

  printf("Encrypted: %s", encrypted);

  free(text);
  exit(EXIT_SUCCESS);
}

Produzione:

Input string to be hashed: hello there
Encrypted: $2b$15$DkpZq2vJRQoBiK4slxfFa.Eml8PUtFB7CYYH1RJH6XML3ujhX8fqy

Utilizzare rigide routine di gestione degli errori per garantire la corretta esecuzione delle funzioni crypt

Il codice di esempio precedente prende la stringa di input dall’utente e alloca la memoria dinamica per memorizzarla. Quindi, dobbiamo assicurarci che la stringa venga letta senza alcun carattere residuo nel buffer stdio. Per questo, chiamiamo fflush su stdout e poi chiamiamo fgets per prendere la stringa di input dall’utente. Inoltre, è bene controllare tutte le funzioni di libreria e le chiamate di sistema per i loro valori di ritorno di errore e chiamare perror per visualizzare il messaggio corrispondente.

#include "crypt.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

enum { MAX_LEN = 1024 };

int main(int argc, char *argv[]) {
  char *text, *encrypted, *salt;
  size_t len;
  long lnmax;

  text = malloc(MAX_LEN);
  if (text == NULL) {
    perror("malloc");
    exit(EXIT_FAILURE);
  }

  printf("Input string to be hashed: ");
  fflush(stdout);
  if (fgets(text, MAX_LEN, stdin) == NULL) exit(EXIT_FAILURE);

  len = strlen(text);
  if (text[len - 1] == '\n') text[len - 1] = '\0';

  salt = crypt_gensalt("$2b$", 15, NULL, 0);
  if (salt == NULL) {
    perror("crypt_gensalt");
    exit(EXIT_FAILURE);
  }

  encrypted = crypt(text, salt);
  if (encrypted == NULL) {
    perror("crypt_gensalt");
    exit(EXIT_FAILURE);
  }

  printf("Encrypted: %s", encrypted);

  free(text);
  exit(EXIT_SUCCESS);
}

Produzione:

Input string to be hashed: hello there
Encrypted: $2b$15$DkpZq2vJRQoBiK4slxfFa.Eml8PUtFB7CYYH1RJH6XML3ujhX8fqy
Autore: Jinku Hu
Jinku Hu avatar Jinku Hu avatar

Founder of DelftStack.com. Jinku has worked in the robotics and automotive industries for over 8 years. He sharpened his coding skills when he needed to do the automatic testing, data collection from remote servers and report creation from the endurance test. He is from an electrical/electronics engineering background but has expanded his interest to embedded electronics, embedded programming and front-/back-end programming.

LinkedIn Facebook