Genera hash SHA in C ++ usando la libreria OpenSSL

Come posso generare gli hash SHA1 o SHA2 usando la libarary OpenSSL ?

Ho cercato su google e non ho trovato alcuna funzione o codice di esempio.

Dalla riga di comando, è semplicemente:

printf "compute sha1" | openssl sha1 

Puoi invocare la libreria in questo modo:

 #include  #include  #include  int main() { unsigned char ibuf[] = "compute sha1"; unsigned char obuf[20]; SHA1(ibuf, strlen(ibuf), obuf); int i; for (i = 0; i < 20; i++) { printf("%02x ", obuf[i]); } printf("\n"); return 0; } 

OpenSSL ha una documentazione orribile senza esempi di codice, ma eccoti:

 #include  bool simpleSHA256(void* input, unsigned long length, unsigned char* md) { SHA256_CTX context; if(!SHA256_Init(&context)) return false; if(!SHA256_Update(&context, (unsigned char*)input, length)) return false; if(!SHA256_Final(md, &context)) return false; return true; } 

Uso:

 unsigned char md[SHA256_DIGEST_LENGTH]; // 32 bytes if(!simpleSHA256(, , md)) { // handle error } 

Successivamente, md conterrà il digest del messaggio binario SHA-256. Un codice simile può essere usato per gli altri membri della famiglia SHA, basta sostituire “256” nel codice.

Se disponi di dati più grandi, devi naturalmente inserire i blocchi dati al loro arrivo (più chiamate SHA256_Update ).

dovrebbe essere la syntax corretta a linea di comando

 echo -n "compute sha1" | openssl sha1 

altrimenti si cancellerà anche il carattere finale di fine riga.

Ecco l’esempio OpenSSL del calcolo del digest sha-1 usando BIO :

 #include  #include  std::string sha1(const std::string &input) { BIO * p_bio_md = nullptr; BIO * p_bio_mem = nullptr; try { // make chain: p_bio_md <-> p_bio_mem p_bio_md = BIO_new(BIO_f_md()); if (!p_bio_md) throw std::bad_alloc(); BIO_set_md(p_bio_md, EVP_sha1()); p_bio_mem = BIO_new_mem_buf((void*)input.c_str(), input.length()); if (!p_bio_mem) throw std::bad_alloc(); BIO_push(p_bio_md, p_bio_mem); // read through p_bio_md // read sequence: buf <<-- p_bio_md <<-- p_bio_mem std::vector buf(input.size()); for (;;) { auto nread = BIO_read(p_bio_md, buf.data(), buf.size()); if (nread < 0) { throw std::runtime_error("BIO_read failed"); } if (nread == 0) { break; } // eof } // get result char md_buf[EVP_MAX_MD_SIZE]; auto md_len = BIO_gets(p_bio_md, md_buf, sizeof(md_buf)); if (md_len <= 0) { throw std::runtime_error("BIO_gets failed"); } std::string result(md_buf, md_len); // clean BIO_free_all(p_bio_md); return result; } catch (...) { if (p_bio_md) { BIO_free_all(p_bio_md); } throw; } } 

Sebbene sia più lungo della sola chiamata alla funzione SHA1 da OpenSSL , è più universale e può essere rielaborato per l'utilizzo con flussi di file (quindi l'elaborazione di dati di qualsiasi lunghezza).