【问题标题】:two different hash values for same string相同字符串的两个不同哈希值
【发布时间】:2012-01-06 13:26:56
【问题描述】:

我需要比较两个字符串的哈希值。 我使用字符串“模板”进行测试。 但是我得到了这个字符串的不同哈希值,所以它总是不一样的。 我使用 CryptoApi 和 MD4

int _tmain(int argc, _TCHAR* argv[])
{
    std::hash_map<int,int> table;
    HCRYPTPROV hProv1,hProv2;
    BYTE *pbBuffer1=(BYTE*)"template";//data to hash
    DWORD dwBufferLen1=strlen((char*)pbBuffer1)+1;
    HCRYPTHASH hHash1,hHash2;
    //first hash
    CryptAcquireContext(&hProv1,NULL,NULL,PROV_RSA_AES,0);
    CryptCreateHash(hProv1,CALG_MD4,0,0,&hHash1);
    CryptHashData(hHash1,pbBuffer1,dwBufferLen1,0);
    /*---------*/
    BYTE *pbBuffer2=(BYTE*)"template";//data to hash
    DWORD dwBufferLen2=strlen((char*)pbBuffer2)+1;
    //second hash
    CryptAcquireContext(&hProv2,NULL,NULL,PROV_RSA_AES,0);  
    CryptCreateHash(hProv2,CALG_MD4,0,0,&hHash2);
    CryptHashData(hHash2,pbBuffer2,dwBufferLen2,0);
    if (hHash1==hHash2)
        printf("The Same\n");
    else printf("Not same\n");
    /*---------*/
    std::cout<<hHash1<<std::endl;
    std::cout<<hHash2<<std::endl;
    if (hProv1)
        CryptReleaseContext(hProv1,0);
    if (hProv2)
        CryptReleaseContext(hProv2,0);
    system("pause");
    return 0;
} 

例如hHash1中的哈希值

691136

hHash2中的哈希值

691216

【问题讨论】:

  • C 标记替换为 c++。 C中没有::
  • 你用调试器单步调试了吗?两个字符串总是产生相同的哈希值,所以它们一定是不同的。

标签: c++ cryptoapi


【解决方案1】:

HCRPTHASHULONG_PTR 类型定义,根据 here。这意味着它是一个指针:

HCRYPTHASH 数据类型用于表示散列对象的句柄。这些句柄向 CSP 模块指示在特定操作中正在使用哪个散列。 CSP 模块不支持直接操作散列值。相反,用户通过哈希句柄来操作哈希值。

typedef ULONG_PTR HCRYPTHASH;

将指针与== 进行比较就像将果冻(或美国公民的果冻)钉在树上或尝试训练猫一样高效:-)

您看到的“哈希”值实际上是指针,相隔 80 个字节(因为它们是指向两个不同内存块的指针)。

为了从句柄中获取 实际哈希,您需要类似以下内容,它会打印十六进制数字:

CHAR hexDigits[] = "0123456789abcdef";
BYTE md4Hash[MD4LEN];
DWORD cbHash = MD4LEN;
if (CryptGetHashParam (hHash1, HP_HASHVAL, md4Hash, &cbHash, 0)) {
    printf("MD4 hash is: ");
    for (DWORD i = 0; i < cbHash; i++) {
        printf ("%c%c", hexDigits[md4Hash[i] >> 4], hexDigits[md4Hash[i] & 0xf]);
    }
    printf("\n");
} else {
    DWORD dwStatus = GetLastError();
    printf ("CryptGetHashParam failed with code %d\n", dwStatus); 
}

为了比较两个哈希值,你可以这样做:

BYTE md4Hash1[MD4LEN], md4Hash2[MD4LEN];
DWORD cbHash1 = MD4LEN, cbHash2 = MD4LEN;

CryptGetHashParam (hHash1, HP_HASHVAL, md4Hash1, &cbHash1, 0);
CryptGetHashParam (hHash2, HP_HASHVAL, md4Hash2, &cbHash2, 0);

if ((cbHash1 == cbHash2) &&
    (memcmp (md4Hash1, md4Hash2, cbHash1) == 0))
{
    // they are equal.
}

【讨论】:

  • 我已经这样做了。我调用 CryptGetHashParam 并将 hHash1hHash2 的字节放入数组中,然后将其与 memcmp 进行比较,它似乎工作正常。
  • @Артём,这基本上是我搜索后的结果 - 请参阅更新的答案。
【解决方案2】:

正如其他答案所指出的,hHash1hHash2 是不透明的句柄——比较它们是没有意义的,因为这类似于比较具有相同值的两个不同对象的地址。

使用CryptGetHashParam 获取哈希值并进行比较:

CryptGetHashParam 函数检索控制哈希对象操作的数据。 可以使用该函数获取实际的哈希值。

【讨论】:

    【解决方案3】:

    hHash1 和 hHash2 不是哈希码,而是句柄。

    http://msdn.microsoft.com/en-us/library/windows/desktop/aa379908(v=vs.85).aspx

    【讨论】:

      猜你喜欢
      • 2021-09-21
      • 2018-07-28
      • 2021-05-09
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 1970-01-01
      • 2011-07-27
      • 2017-02-14
      相关资源
      最近更新 更多