可以用 wincrypt 做 HMAC 吗?

2024-01-05

我一直在尝试使用 wincrypt/cryptoapi/Cryptography API: Next Generation (CNG) 执行直接的 SHA256 HMAC,但我真的很挣扎。我的目标是 Windows 8。

我找不到正确的方法或在任何地方找到任何例子。我希望在 C/C++ 中执行以下操作,这在下面的 C# 中进行了演示

        HMAC hashMaker = new HMACSHA256(Encoding.ASCII.GetBytes("SecretKey"));
        byte[] hash = hashMaker.ComputeHash(Encoding.ASCII.GetBytes("<SomeXmlData />"));
        string hashStr = BitConverter.ToString(hash);

它返回哈希值:B2-42-48-67-5A-B8-03-87-5B-00-D7-8C-65-5A-AE-B7-92-E3-F9-27-40-C1-01 -A5-37-74-E1-65-51-9F-F6-6A。

有人成功使用 cryptoapi 执行直接的 HMAC 吗?


谢谢你提供的信息。我从来不知道 BCrypt 的方法集。 HMAC 比 wincrypt/cryptoapi 的 CryptHashData 容易得多。从使用的例子来看使用 SHA256 进行哈希处理 http://msdn.microsoft.com/en-us/library/windows/desktop/aa376217%28v=vs.85%29.aspx我能够创建 HMAC 代码。您只需要添加BCRYPT_ALG_HANDLE_HMAC_FLAG http://msdn.microsoft.com/en-us/library/windows/desktop/aa375479%28v=vs.85%29.aspxBCryptOpenAlgorithmProvider 的最后一个参数并将密钥包含在调用中BCrypt创建哈希 http://msdn.microsoft.com/en-us/library/windows/desktop/aa375383%28v=vs.85%29.aspx.

这是完成的代码:

#include <windows.h>
#include <stdio.h>
#include <bcrypt.h>
#pragma comment(lib, "bcrypt.lib") 
#define NT_SUCCESS(Status)          (((NTSTATUS)(Status)) >= 0)

#define STATUS_UNSUCCESSFUL         ((NTSTATUS)0xC0000001L)

void __cdecl wmain(
    int                      argc,
    __in_ecount(argc) LPWSTR *wargv)
{
    BCRYPT_ALG_HANDLE       hAlg = NULL;
    BCRYPT_HASH_HANDLE      hHash = NULL;
    NTSTATUS                status = STATUS_UNSUCCESSFUL;
    DWORD                   cbData = 0,
        cbHash = 0,
        cbHashObject = 0;
    PBYTE                   pbHashObject = NULL;
    PBYTE                   pbHash = NULL;
    CONST BYTE key[] = { "SecretKey" };
    CONST BYTE message[] = { "<SomeXmlData />" };

    //open an algorithm handle
    if (!NT_SUCCESS(status = BCryptOpenAlgorithmProvider(
        &hAlg,
        BCRYPT_SHA256_ALGORITHM,
        NULL,
        BCRYPT_ALG_HANDLE_HMAC_FLAG)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptOpenAlgorithmProvider\n", status);
        goto Cleanup;
    }

    //calculate the size of the buffer to hold the hash object
    if (!NT_SUCCESS(status = BCryptGetProperty(
        hAlg,
        BCRYPT_OBJECT_LENGTH,
        (PBYTE)&cbHashObject,
        sizeof(DWORD),
        &cbData,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
        goto Cleanup;
    }

    //allocate the hash object on the heap
    pbHashObject = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHashObject);
    if (NULL == pbHashObject)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    //calculate the length of the hash
    if (!NT_SUCCESS(status = BCryptGetProperty(
        hAlg,
        BCRYPT_HASH_LENGTH,
        (PBYTE)&cbHash,
        sizeof(DWORD),
        &cbData,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptGetProperty\n", status);
        goto Cleanup;
    }

    //allocate the hash buffer on the heap
    pbHash = (PBYTE)HeapAlloc(GetProcessHeap(), 0, cbHash);
    if (NULL == pbHash)
    {
        wprintf(L"**** memory allocation failed\n");
        goto Cleanup;
    }

    //create a hash
    if (!NT_SUCCESS(status = BCryptCreateHash(
        hAlg,
        &hHash,
        pbHashObject,
        cbHashObject,
        (PBYTE)key,
        sizeof(key)-1,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptCreateHash\n", status);
        goto Cleanup;
    }

    //hash some data
    if (!NT_SUCCESS(status = BCryptHashData(
        hHash,
        (PBYTE)message,
        sizeof(message)-1,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptHashData\n", status);
        goto Cleanup;
    }

    //close the hash
    if (!NT_SUCCESS(status = BCryptFinishHash(
        hHash,
        pbHash,
        cbHash,
        0)))
    {
        wprintf(L"**** Error 0x%x returned by BCryptFinishHash\n", status);
        goto Cleanup;
    }

    printf("The hash is:  ");
    for (DWORD i = 0; i < cbHash; i++)
    {
        printf("%2.2X-", pbHash[i]);
    }


Cleanup:

    if (hAlg)
    {
        BCryptCloseAlgorithmProvider(hAlg, 0);
    }

    if (hHash)
    {
        BCryptDestroyHash(hHash);
    }

    if (pbHashObject)
    {
        HeapFree(GetProcessHeap(), 0, pbHashObject);
    }

    if (pbHash)
    {
        HeapFree(GetProcessHeap(), 0, pbHash);
    }
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

可以用 wincrypt 做 HMAC 吗? 的相关文章

随机推荐

  • 它什么时候会在 Android 应用程序的 admob 上生效

    我制作了集成admob的Android应用程序 然后我在我的测试设备上运行这个应用程序 它会在屏幕上显示广告横幅 但广告的状态仍然是无效的 这让我很困惑 你知道admob什么时候激活吗 运行这个从市场商店下载的应用程序 提前致谢 AdMob
  • 测试路径/System.IO.Directory::Exists 未按预期工作

    我在使用 Powershell CmdLet 测试路径时遇到问题 我在服务器上创建了共享 Servername MyShare 它允许一组用户仅创建文件并附加数据 而其他用户只能读取和删除这些文件 第一组不允许执行任何其他操作 包括读取权限
  • 我如何在 PHPExcel 中制作项目符号列表

    我试图使用将 html 标签从 php 转换为 excelPHPExcel 一切都很顺利 除了我找不到如何制作项目符号列表 PHPExcel 中是否存在此功能 我已经扫描了 PHPExcel 的一些纪录片 但我找不到任何有关子弹的内容 我想
  • 华为系统文件“源代码与字节码不匹配”

    我们正在调试其中一个应用程序的一个问题 该问题仅影响华为设备 为了调试它 我们购买了 P20 Lite ANE LX1 我们在代码中放置了一些断点 并正在调查完整的堆栈跟踪 该设备安装了 Android 8 0 我们在 Android St
  • pthread_create() 如何工作?

    鉴于以下情况 pthread t thread pthread create thread NULL function NULL 到底是做什么的pthread create do to thread 会发生什么thread在它加入主线程并终
  • org.json.JSONException:第 550 个字符处的预期文字值

    我正在尝试从 asset 文件夹中读取 JSON 文件 但我得到以下异常 org json JSONException Expected literal value at character 550 我搜索了很多东西但没有找到任何相关的东西
  • 无法使用CSS网格实现网格布局[重复]

    这个问题在这里已经有答案了 在尝试了解有关 CSS 网格的更多信息时 我尝试创建一些不同的网格布局 我试图创建的内容如下 这是其中的一个步骤 wrapper display grid grid gap 15px grid template
  • 在Android中查看活动堆栈[关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 是否可以查看 Android 中的活
  • 找不到包 java.nio.file

    我的 java 编译器找不到java nio file包裹 考虑 import java nio file public class Test public static void main String args Path current
  • 性能:(比较字符串)与(转换为整数)

    大家好 我是 Stack Overflow 的新手 对 python 也相当陌生 但我已经编写代码多年了 想知道以下哪一种性能更好 假设我已经从操作系统加载了environ 并且环境中的标志保证为 0 或 1 if environ Flag
  • HTML 有序列表缩进以保留原始编号

    我需要缩进有序列表以保持父列表项编号 我拥有的 My code ol li Item 1 li li Item 2 ol li Item 2 1 li li Item 2 2 li ol li li Item 3 li ol 等等 我现在得
  • ruby at_exit 退出状态

    我可以在 at exit 块中确定自己的进程退出状态吗 at exit do if this process status success print Success else print Failure end end 使用来自的想法ta
  • CSS/HTML:如何更改复选框输入中复选标记的颜色? [复制]

    这个问题在这里已经有答案了 如何更改 HTML 复选框输入中复选标记的颜色 这是一个纯 CSS 解决方案 不应破坏屏幕阅读器或默认用户代理操作 此外 四大浏览器的最新版本都支持这一点 如果您添加一些额外的技巧 还有其他一些浏览器 但我将把它
  • ggplot2 中的日期顺序不是按时间顺序排列的

    我正在尝试制作一个图表来描述一段时间内的人口情况 然而 日期并不是按时间顺序排列的 在导入的 CSV 中 日期全部正确且按顺序排列 但是 运行下面的代码后 所显示的图表中的日期顺序不正确 开始日期位于开始日期的中间 结束日期位于开始日期的左
  • 有没有办法使用 Web Audio API 比实时更快地采样音频?

    我正在使用 Web Audio API 并试图找到一种导入 mp3 的方法 因此这仅在 Chrome 中 并在画布上生成它的波形 我可以实时执行此操作 但我的目标是比实时执行得更快 我能够找到的所有示例都涉及在附加到 onaudioproc
  • Inno Setup - 如何显示透明的 PNG 图像?

    我想在欢迎页面上显示它 这怎么可能 在5 5 7更新 2015年12月28日 中 有32位BMP并实现了Alpha通道功能 WizardImageFile 和WizardSmallImageFile Setup 部分指令现在支持带有 Alp
  • 如何忽略不耐烦的用户的多次点击?

    我有一个查询要回答远程客户端的标准请求 标准是指它不从服务器外部获取参数 每当 任何人向某个 URL 提交请求 例如http www example com query http www example com query 他 她得到的内容
  • 使用ripemd160和密钥对Java中的字符串进行哈希模拟php函数hash_hmac

    我正在尝试使用 Java 来哈希字符串ripemd160模拟以下 php 的输出 string string key test hash hmac ripemd160 string key outputs 37241f2513c60ae4d
  • 更新到 Android studio 3.2 时 Gradle 错误

    我将 Android Studio 版本更新至 3 2 现在我的项目面临以下错误 com novoda gradle release AndroidLibrary LibraryUsage getDependencyConstraints
  • 可以用 wincrypt 做 HMAC 吗?

    我一直在尝试使用 wincrypt cryptoapi Cryptography API Next Generation CNG 执行直接的 SHA256 HMAC 但我真的很挣扎 我的目标是 Windows 8 我找不到正确的方法或在任何