2011-05-08 19 views
17

Necesito un ejemplo de cómo utilizar Crypto ++ para generar un hash SHA256 de un std :: string y la salida de un std :: string. Parece que no puedo entenderlo. Todo lo que he probado me da resultados no válidos.Generando un hash SHA256 con Crypto ++, usando una cadena como entrada y salida?

Aquí está el nuevo código después de la respuesta de interjay:

string SHA256(string data) 
{ 
    byte const* pbData = (byte*) data.data(); 
    unsigned int nDataLen = data.size(); 
    byte abDigest[CryptoPP::SHA256::DIGESTSIZE]; 

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen); 

    return string((char*)abDigest); 
} 

La salida para SHA256 ("A"); es

enter image description here

¿Cómo puedo convertir esto en un formato legible?

Gracias a la respuesta de Interjay pude generar el hash final.

+7

Bienvenido al desbordamiento de la pila! No funciona así aquí; tienes que mostrar lo que has intentado, y luego te ayudaremos. –

+2

No elimine las partes de su pregunta que han sido respondidas. – interjay

+2

Si no quiere ayudar, ¿por qué molestarse en comentar? La pregunta fue claramente redactada y comprensible, absolutamente vale la pena responder sin los intentos anteriores. En ninguna parte de la pregunta frecuente se afirma que uno debe mostrar sus intentos anteriores. –

Respuesta

14

Esta línea dará los resultados incorrectos:

unsigned int nDataLen = sizeof(pbData); 

Siempre le dará el tamaño de un puntero. Lo que quiere en su lugar es data.size().

Además, no es necesario esta parte:

if(!CryptoPP::SHA256().VerifyDigest(abDigest, pbData, nDataLen)) 
{ 
    return SHA256(data); 
} 

Siempre debe verificar correctamente, ya que acabas de calcular el compendio sobre la base de los mismos datos. Y si no fuera así, entrarías en una recursión infinita.

Para obtener una salida legible, se puede convertir a hexadecimal. He aquí un ejemplo de MD5 del Crypto++ Wiki, que debería funcionar para usted si se reemplaza MD5 con SHA256:

CryptoPP::MD5 hash; 
byte digest[ CryptoPP::MD5::DIGESTSIZE ]; 
std::string message = "abcdefghijklmnopqrstuvwxyz"; 

hash.CalculateDigest(digest, (byte*) message.c_str(), message.length()); 

CryptoPP::HexEncoder encoder; 
std::string output; 
encoder.Attach(new CryptoPP::StringSink(output)); 
encoder.Put(digest, sizeof(digest)); 
encoder.MessageEnd(); 

std::cout << output << std::endl; 
+0

bien hice esos cambios y aunque ahora me parece estar dando el mismo resultado cada vez, la salida está en todas las galimatías de caracteres extraños al azar. ¿Cómo puedo cambiarlo a un formato legible? – Doug

+0

@Doug Ver mi respuesta editada. – interjay

+0

Al aplicar su ejemplo, se produce un error de conversión de 'const char *' a 'const byte *'. '(byte *) message.c_str()' es la conversión correcta. – EisenHeim

16

Esto da salida a una cadena de base 64 mediante el CryptoPP::Base64Encoder:

#include "sha.h" 
#include "filters.h" 
#include "base64.h" 

std::string SHA256HashString(std::string aString){ 
    std::string digest; 
    CryptoPP::SHA256 hash; 

    CryptoPP::StringSource foo(aString, true, 
    new CryptoPP::HashFilter(hash, 
     new CryptoPP::Base64Encoder (
     new CryptoPP::StringSink(digest)))); 

    return digest; 
} 
+0

¡Fantástico, estaba buscando una forma de hacer esto con el pipeline! – Ethan

+0

CryptoPP también utiliza las instrucciones [SIMD 64] (https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions) que acelerarlo. – ahmd0

0

el código se puede esperar un nulo -cadena terminada del búfer que suministra al constructor de cadenas! Lo que significa que el resultado casi seguro será incorrecto.

para hacer cumplir el formato digest y, utilice el siguiente lugar:

return std::string((char*)abDigest, CryptoPP::SHA256::DIGESTSIZE);

También con respecto a la impresión de que el siguiente correctamente produce el vector de prueba BA7816BF8F01CFEA414140DE5DAE2223B00361A396177A9CB410FF61F20015AD para la cadena "abc"

std::string string_to_hex(const std::string& input) 
{ 
    static const char* const lut = "ABCDEF"; 
    size_t len = input.length(); 

    std::string output; 
    output.reserve(2 * len); 
    for (size_t i = 0; i < len; ++i) 
    { 
    const unsigned char c = input[i]; 
    output.push_back(lut[c >> 4]); 
    output.push_back(lut[c & 15]); 
    } 
    return output; 
} 

std::string SHA256(std::string data) 
{ 
    CryptoPP::byte const* pbData = (CryptoPP::byte*)data.data(); 
    unsigned int nDataLen = data.length(); 
    CryptoPP::byte abDigest[CryptoPP::SHA256::DIGESTSIZE]; 

    CryptoPP::SHA256().CalculateDigest(abDigest, pbData, nDataLen); 

    // return string((char*)abDigest); -- BAD!!! 
    return std::string((char*)abDigest, CryptoPP::SHA256::DIGESTSIZE); 
} 

void test_cryptopp() { 
    std::cout << string_to_hex(SHA256("abc")) << std::endl; 
}