Genere hash SHA en C ++ utilizando la biblioteca OpenSSL

¿Cómo puedo generar hashes SHA1 o SHA2 usando la librería OpenSSL ?

Busqué en google y no pude encontrar ninguna función o código de ejemplo.

Desde la línea de comando, es simplemente:

printf "compute sha1" | openssl sha1 

Puede invocar la biblioteca de esta manera:

 #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 tiene una documentación horrible sin ejemplos de código, pero aquí está:

 #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 } 

Posteriormente, md contendrá el resumen binario del mensaje SHA-256. Se puede usar un código similar para los otros miembros de la familia SHA, simplemente reemplace “256” en el código.

Si tiene datos más grandes, por supuesto debe alimentar los fragmentos de datos a medida que llegan (múltiples llamadas SHA256_Update ).

la syntax correcta en la línea de comando debería ser

 echo -n "compute sha1" | openssl sha1 

de lo contrario, también hash el carácter de nueva línea final.

Aquí está el ejemplo de OpenSSL de calcular el resumen 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; } } 

Aunque es más que llamar a la función SHA1 de OpenSSL , pero es más universal y se puede volver a trabajar para utilizar con secuencias de archivos (procesando datos de cualquier longitud).