1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

C++ で ハッシュ値を生成する。 Windows OpenSSL編

Posted at

C, C++の標準ライブラリでは、SHA系アルゴリズムを生成するクラス、関数が、提供されていないです。
今回は、OpenSSLの関数でハッシュ値を生成しました。

実施環境

  • OpenSSL 3.0系
  • Visual Stuido 2022 Commnunity

OpenSSLのインストール

Win32/Win64 OpenSSLより Windows版 OpenSSLをダウンロードして、インストールします。64bit版のサンプルを作成するので、「Win64 OpenSSL v3.0.7」をインストールしました。

プロジェクトの設定

サンプルのプロジェクトの「追加のインクルードディレクトリ」に C:\Program Files\OpenSSL-Win64\include を追加します。「追加のライブラリディレクトリ」に C:\Program Files\OpenSSL-Win64\lib\VC を追加します。「追加のライブラリファイル」に libcrypto64MD.lib を追加します。

サンプルプログラム

その1

おそらく、コードが一番、短くて済む方法?。 関数 SHA256 を使います。

#include <iostream>
#include <string>
#include <vector>
#include <openssl/sha.h>

int main()
{
    std::string str("Hello World");
    
    unsigned char uchash1[20];
    size_t  hashSize1 = sizeof(uchash1);
    unsigned char uchash2[32];
    size_t hashSize2 = sizeof(uchash2);

    SHA1((const unsigned char *)str.data(), str.size(), uchash1);
    SHA256((const unsigned char*)str.data(), str.size(), uchash2);

    std::vector<unsigned char> hash1;
    hash1.resize(hashSize1);
    for (size_t i = 0; i < hashSize1; i++) {
        hash1.at(i) = uchash1[i];
    }

    std::vector<unsigned char> hash2;
    hash2.resize(hashSize2);
    for (size_t i = 0; i < hashSize2; i++) {
        hash2.at(i) = uchash2[i];
    }

    std::cout << "SHA1" << std::endl;
    for (size_t i = 0; i < hash1.size(); i++) {
        std::cout << std::hex << (int)hash1.at(i);
    }
    std::cout << std::endl;

    std::cout << "SHA256" << std::endl;
    for (size_t i = 0; i < hash2.size(); i++) {
        std::cout << std::hex << (int)hash2.at(i);
    }
    std::cout << std::endl;
}

その2

ハッシュ値の生成を細かく制御したい場合は、EVP digestを使います。

#include <iostream>
#include <string>
#include <vector>
#include <openssl/evp.h>

int main()
{
    std::string str("Hello World");

    EVP_MD_CTX* mdctx;
    const EVP_MD* md;

    md = EVP_get_digestbyname("SHA1");
    if (md == NULL) {
        printf("Unknown message digest %s\n", "SHA1");
        exit(1);
    }

    mdctx = EVP_MD_CTX_new();
    if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
        printf("Message digest initialization failed.\n");
        EVP_MD_CTX_free(mdctx);
        exit(1);
    }

    if (!EVP_DigestUpdate(mdctx, str.data(), str.size())) {
        printf("Message digest update failed.\n");
        EVP_MD_CTX_free(mdctx);
        exit(1);
    }

    unsigned char uchash1[20];
    unsigned int  hashSize1;

    if (!EVP_DigestFinal_ex(mdctx, uchash1, &hashSize1)) {
        printf("Message digest finalization failed.\n");
        EVP_MD_CTX_free(mdctx);
        exit(1);
    }
    EVP_MD_CTX_free(mdctx);

    std::vector<unsigned char> hash1;
    hash1.resize(hashSize1);
    for (size_t i = 0; i < hashSize1; i++) {
        hash1.at(i) = uchash1[i];
    }

    std::cout << "SHA1" << std::endl;
    for (size_t i = 0; i < hash1.size(); i++) {
        std::cout << std::hex << (int)hash1.at(i);
    }
    std::cout << std::endl;


    md = EVP_get_digestbyname("SHA256");
    if (md == NULL) {
        printf("Unknown message digest %s\n", "SHA256");
        exit(1);
    }

    mdctx = EVP_MD_CTX_new();
    if (!EVP_DigestInit_ex2(mdctx, md, NULL)) {
        printf("Message digest initialization failed.\n");
        EVP_MD_CTX_free(mdctx);
        exit(1);
    }

    if (!EVP_DigestUpdate(mdctx, str.data(), str.size())) {
        printf("Message digest update failed.\n");
        EVP_MD_CTX_free(mdctx);
        exit(1);
    }

    unsigned char uchash2[32];
    unsigned int  hashSize2;

    if (!EVP_DigestFinal_ex(mdctx, uchash2, &hashSize2)) {
        printf("Message digest finalization failed.\n");
        EVP_MD_CTX_free(mdctx);
        exit(1);
    }
    EVP_MD_CTX_free(mdctx);

    std::vector<unsigned char> hash2;
    hash2.resize(hashSize2);
    for (size_t i = 0; i < hashSize2; i++) {
        hash2.at(i) = uchash2[i];
    }

    std::cout << "SHA256" << std::endl;
    for (size_t i = 0; i < hash2.size(); i++) {
        std::cout << std::hex << (int)hash2.at(i);
    }
    std::cout << std::endl;

}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?