c++ - 带密码学 API C/C++ 的 HMAC

标签 c++ c cryptography cryptoapi

我正在使用 http://msdn.microsoft.com/en-us/library/aa382379(v=vs.85).aspx 中的 Microsoft 示例.它编译得很好并且看起来工作正常,返回结果:

48 f2 57 38 29 29 43 16 fd f4 db 58 31 e1 0c 74 48 8e d4 e2

但是,当我使用下面的 C# 代码运行相同的计算时,我得到了不同的哈希值?

4C-2D-E3-61-BA-89-58-55-8D-E3-D0-49-ED-1F-B5-C1-15-65-6E-65

        HMAC hashMaker = new HMACSHA1(new byte[]{0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64});
        byte[] hash = hashMaker.ComputeHash(new byte[] {0x6D,0x65,0x73,0x73,0x61,0x67,0x65});
        string hashStr = BitConverter.ToString(hash);

我担心示例 C 代码在某些方面是正确的。这里发生了什么?

最佳答案

发布的 C# 代码和链接(但未发布)的 C 代码做不同的事情。因此,输出也会有所不同。

WinCrypt 代码执行以下操作:

  • 创建 key 字节的 SHA1 散列
  • 使用 RC4 从生成的哈希中导出 session key
  • 使用派生 key 初始化 HMAC_SHA1 摘要
  • 使用 HMAC 执行 HMAC CryptHashData
  • 请求生成的哈希字节

C# 代码执行以下操作:

  • 使用 key 字节作为实际 key 创建 HMAC_SHA1(无推导)
  • 通过 ComputeHash 执行 HMAC,返回生成的哈希摘要

换句话说,它们之所以不同,是因为它们在做不同的事情。哪一个是“正确的”取决于你想做什么(问题中没有提到)。

OpenSSL等同于C#代码

unsigned char key[] = { 0x70,0x61,0x73,0x73,0x77,0x6F,0x72,0x64 };
unsigned char bytes[] = { 0x6D,0x65,0x73,0x73,0x61,0x67,0x65 };
unsigned char md[32] = {0};
unsigned int md_len = (int)sizeof(md);

HMAC_CTX ctx;
HMAC_CTX_init(&ctx);
HMAC_Init(&ctx, key, (int)sizeof(key), EVP_sha1());
HMAC_Update(&ctx, bytes, sizeof(bytes));
HMAC_Final(&ctx, md, &md_len);

md 中生成的摘要分别与 C# 代码匹配(省略,但相信我的话或自己测试)。

关于c++ - 带密码学 API C/C++ 的 HMAC,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22113805/

相关文章:

CodeChef 运行时错误(sigsegv)

C:试图颠倒矩阵中 10 个单词的顺序

javascript - 为什么 Node crypto 会为同一个字符串返回不同的值?

java - PBEWithHmacSHA512AndAES_128 和 AES 模式(如 GCM)

c++ - 我可以让子类隐式继承基类构造函数吗?

c++ - 在 C++ 和 C 之间传递数据

c - 如何检测堆栈溢出点

c - 如何导出使用 CryptoAPI 派生的 AES key

c++ - 为什么 boost 包含两个不同版本的 strong_typedef.hpp?

c++ - 禁止从构造函数调用纯虚方法的编译器选项