2009-05-28 111 views

Respuesta

70

Desde la línea de comandos, es simplemente:

printf "compute sha1" | openssl sha1 

puede invocar la biblioteca de la siguiente manera:

#include <stdio.h> 
#include <string.h> 
#include <openssl/sha.h> 

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

+7

no olvides vincular contra libcrypto y libssl – AbiusX

+5

Usar SHA256 (ibuf, strlen (ibuf), obuf) ;, es más seguro. – HighLife

+6

en C++ su código give ::: 'strlen': no ​​se puede convertir el parámetro 1 de 'unsigned char [13]' a 'const char *' –

48

OpenSSL tiene una terrible documentation sin ejemplos de código, pero aquí usted es:

#include <openssl/sha.h> 

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(<data buffer>, <data length>, md)) 
{ 
    // handle error 
} 

Después, md contendrá el binario mensaje SHA-256 digerido. 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 (llamadas múltiples SHA256_Update).

+1

El código es bueno, pero omite la verificación del valor de retorno. Podría mejorarse ya que su código de alta integridad. Mucha gente lo copiará/pegará sin pensarlo ni revisarlo. – jww

+0

No hay valor de retorno. Solo mira la documentación vinculada. – AndiDog

+0

Suena como los antiguos 0.9.8 documentos. – jww

2

sintaxis correcta en la línea de comandos debe ser

echo -n "compute sha1" | openssl sha1 

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

1

Aquí es OpenSSL ejemplo de cálculo de SHA-1 digerir usando BIO:

#include <openssl/bio.h> 
#include <openssl/evp.h> 

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<char> 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 largo que acaba de llamar a SHA1 función de OpenSSL, pero es más universal y puede ser reelaborado para usar con flujos de archivos (procesando datos de cualquier longitud).

Cuestiones relacionadas