SHA256を調べてみたらひとまず、OPENSSLインストールして・・・
のように、何かインストールしてといった話から始まるわけですが、
諸事情によりインストールを避けたいというのとWindows限定でしか使わないということから以下のコードにたどり着いた。
#include <stdio.h>
#include <windows.h>
#include <wincrypt.h>
int SHA256(BYTE* data, DWORD dataSize, BYTE* hash, DWORD* hashSize) {
	int result = 0;
	HCRYPTPROV hProv = 0;
	HCRYPTHASH hHash = 0;
	if (!CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){ goto LAST; }
	if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) { goto LAST; }
	if (!CryptHashData(hHash, data, dataSize, 0)) { goto LAST; }
	if (!CryptGetHashParam(hHash, HP_HASHVAL, hash, hashSize, 0)) { goto LAST; }
	result = 1;
LAST:
	if (hHash) { CryptDestroyHash(hHash); }
	if (hProv) { CryptReleaseContext(hProv, 0); }
	return result;
}
int main() {
	const char* str = "Hello SHA256";
	BYTE hash[32] = { 0 };
	DWORD hashSize = sizeof(hash);
	
	if (SHA256((BYTE*)str, strlen(str), hash, &hashSize)) {
		for (DWORD i = 0; i < hashSize; i++) {
			printf("%02x", hash[i]);
		}
		
		printf("\n");
	}
		return 0;
}
ただし、CryptHashData 関数 は、非推奨とのこと。
大事な この API は非推奨です。 新規および既存のソフトウェアでは 、暗号化次世代 API の 使用を開始する必要があります。Microsoft は、今後のリリースでこの API を削除する可能性があります。 CryptHashData 関数 (wincrypt.h)
70725d0f78cb0967c0e5171f733619712d239e28f2d279e4b3c3ed97f7456fa3
そんなわけで、書き換えるとこんな感じらしい。
#include <stdio.h>
#include <windows.h>
#include <bcrypt.h>
#include <ntstatus.h>
#include <vector>
#include <string.h>
#pragma comment(lib, "bcrypt.lib")
std::vector<BYTE> SHA256(const BYTE* data, DWORD dataSize)
{
    BCRYPT_ALG_HANDLE hAlg = NULL;
    BCRYPT_HASH_HANDLE hHash = NULL;
    std::vector<BYTE> hash;
    DWORD hashSize = 0, cbData = 0;
    NTSTATUS status = STATUS_UNSUCCESSFUL;
    do {
        // アルゴリズムプロバイダーを開く
        status = BCryptOpenAlgorithmProvider(&hAlg, BCRYPT_SHA256_ALGORITHM, NULL, 0);
        if (!BCRYPT_SUCCESS(status)) break;
        // ハッシュオブジェクトのサイズを取得
        status = BCryptGetProperty(hAlg, BCRYPT_OBJECT_LENGTH, (PBYTE)&cbData, sizeof(DWORD), &hashSize, 0);
        if (!BCRYPT_SUCCESS(status)) break;
        // ハッシュオブジェクトを作成
        std::vector<BYTE> hashObject(cbData);
        status = BCryptCreateHash(hAlg, &hHash, hashObject.data(), (ULONG)hashObject.size(), NULL, 0, 0);
        if (!BCRYPT_SUCCESS(status)) break;
        // データをハッシュ化
        status = BCryptHashData(hHash, (PBYTE)data, dataSize, 0);
        if (!BCRYPT_SUCCESS(status)) break;
        // ハッシュサイズを取得
        status = BCryptGetProperty(hAlg, BCRYPT_HASH_LENGTH, (PBYTE)&hashSize, sizeof(DWORD), &cbData, 0);
        if (!BCRYPT_SUCCESS(status)) break;
        // 最終的なハッシュ値を取得
        hash.resize(hashSize);
        status = BCryptFinishHash(hHash, hash.data(), hashSize, 0);
        if (!BCRYPT_SUCCESS(status)) hash.clear();
    } while (false);
    if (hHash) BCryptDestroyHash(hHash);
    if (hAlg) BCryptCloseAlgorithmProvider(hAlg, 0);
    return hash;
}
int main() {
    const char* str = "Hello SHA256";
    DWORD dataSize = strlen(str);  // 正しい入力データサイズを使用
    std::vector<BYTE> hash = SHA256((BYTE*)str, dataSize);
    for (BYTE b : hash) {
        printf("%02x", b);
    }
    printf("\n");
    return 0;
}
gotoで最後にまとめて解放するコードにしていたら、初期化(std::vector
70725d0f78cb0967c0e5171f733619712d239e28f2d279e4b3c3ed97f7456fa3