2009-05-28 85 views

答えて

70

コマンドラインから、それは単にです:

printf "compute sha1" | openssl sha1 

あなたはこのようにライブラリを呼び出すことができます。

#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

libcryptoとlibsslとのリンクを忘れないでください。 – AbiusX

+5

SHA256(ibuf、strlen(ibuf)、obuf);を使用すると、より安全です。 – HighLife

+6

in C++あなたのコードで::: 'strlen':パラメータ1を 'unsigned char [13]'から 'const char *'に変換できません –

48

OpenSSLはありませんコード例で恐ろしいdocumentationを持っているが、ここであなたは:

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

使用法:

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

その後、mdバイナリSHA-256メッセージダイジェストを含むであろう。同様のコードを他のSHAファミリのメンバに使用できます。コード内の "256"を置き換えてください。

データが大きい場合は、もちろんデータチャンクが到着したときにフィードする必要があります(複数のSHA256_Updateコール)。コマンドラインで

+1

コードは良好ですが、戻り値のチェックは省略されています。それは、高い完全性のコードから改善することができます。たくさんの人が考えたりチェックしたりせずにコピー/ペーストします。 – jww

+0

戻り値はありません。リンクされたドキュメントを見てください。 – AndiDog

+0

古い0.9.8ドキュメントのように聞こえます。 – jww

2

正しい構文は、そうでないあなたにも末尾に改行文字をハッシュう

echo -n "compute sha1" | openssl sha1 

でなければなりません。ここで

1

SHA-1を計算するOpenSSLの例は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; 
    } 
} 

それが長いだけOpenSSLのからSHA1関数を呼び出すよりもだが、それは、より普遍的だとすることができますがファイルストリームを使用するために再加工されます(したがって、任意の長さのデータを処理します)。

関連する問題