利用Crypto API实现Hash算法(补充SHA256、SHA512)

标签:
sha256cryptoapi哈希算法md5 |
分类: C&&CPP |
--------------------------------------------------------------------------------------
Step0:
Step1:
首先我们先看看这个函数,CryptHashData(看起来很靠谱的样子,其实只算一个中间函数吧。)
BYTE *pbData,
DWORD dwDataLen,//待哈希数据长度
DWORD dwFlags
);
参数:
hHash
[in]哈希对象句柄
pbData
[in]指向要加入到哈希对象的数据指针
dwDataLen
[in]数据长度
dwFlags
[in]标志
CRYPT_USERDATA 所有微软CSP 都忽略此参数。所有其他CSP 都不能忽略此参数,如果置此参数,CSP 提示用户直接传入数据。
函数功能:
此函数把一段数据加入到指定的哈希对象中去。
e.g.
CryptHashData(hCryptHash, (BYTE*)hash_data, data_len, 0);
Step2:
BOOL WINAPI CryptCreateHash(HCRYPTPROV hProv,
ALG_ID Algid, //想使用的哈希算法
HCRYPTKEY hKey,
DWORD dwFlags,
HCRYPTHASH *phHash
//获得的哈希句柄
);
参数:
hProv
[in]CSP 句柄
Algid
[in]哈希算法的标示符。
hKey
[in]如果哈希算法是密钥哈希,如HMAC、MAC 算法,就用此密钥句柄传递密钥。对于非密钥算法,此参数为NULL。
dwFlags
[in]保留。必须为0。
phHash
[out]哈希对象的句柄。
功能:
此函数初始化哈希数据流。它创建并返回了一个CSP 哈希对象的句柄。此句柄由CryptHashData 和CryptHashSessionKey 来调用。
Step3:
LPCTSTR pszContainer,
LPCTSTR pszProvider,
DWORD dwProvType,
DWORD dwFlags
);
参数:
phProv
[out] CSP 句柄指针
pszContainer
[in] 密钥容器名称, 指向密钥容器的字符串指针。如果dwFlags 为
CRYPT_VERIFYCONTEXT,pszContainer 必须为NULL。
pszProvider
[in]指向CSP 名称的字符串指针。如果为NULL,就使用却省的CSP。
dwProvType
[in]CSP 类型。
dwFlags
[in]标志。
CRYPT_VERIFYCONTEXT
此选项指出应用程序不需要使用公钥/私钥对,如程序只执行哈希和对称加密。
只有程序需要创建签名和解密消息时才需要访问私钥。
CRYPT_NEWKEYSET
使用指定的密钥容器名称创建一个新的密钥容器。如果pszContainer 为NULL,
密钥容器就使用却省的名称创建。
CRYPT_MACHINE_KEYSET
由此标志创建的密钥容器只能由创建者本人或有系统管理员身份的人使用。
CRYPT_DELETEKEYSET
删除由pszContainer 指定的密钥容器。如果pszContainer 为NULL,却省名称
的容器就会被删除。此容器里的所有密钥对也会被删除。
CRYPT_SLIENT
应用程序要求CSP 不显示任何用户界面。
功能:
这个函数是用来取得指定CSP 密钥容器句柄,以后的任何加密操作就是针对此CSP 句
柄而言。函数首先查找由dwProvType 和pszProvider 指定的CSP,如果找到了CSP,函数就查找由此CSP 指定的密钥容器。由适当的dwFlags 标志,这个函数就可以创建和销毁密钥容器,如果不要求访问私钥的话,也可以提供对CSP 临时密钥容器的访问。
Step4:
DWORD dwParam,//你需要的结果类型
BYTE *pbData,//存储结果的缓冲区指针
DWORD *pdwDataLen,
//最大缓冲区长度
DWORD dwFlags
);
参数:
hHash
[in]哈希对象的句柄
dwParam
[in]查询类型。可以是下列:
HP_ALGID 哈希算法
HP_HASHSIZE 哈希值长度
HP_HASHVAL 哈希值,由hHash 指定的哈希值或者消息哈希
功能:
此函数得到指定哈希对象的数据。
① pdwDataLen参数是输入输出的,特别要注意它的初始值,一旦小于哈希值长度,将返回莫名其妙的结果。用GetLastError可以获取错误代码234,即ERROR_MORE_DATA。
与最终结果对比上图:
http://s3/mw690/002S5apNzy6KUpe6pwud2&690API实现Hash算法(补充SHA256、SHA512)" TITLE="利用Crypto
②对以上四个函数最好都进行返回值判断,如果返回值为假,表示执行出了问题,这时可以用GetLastError获取错误信息,查找Error Code搞清楚错误原因,不然会有莫名其妙的结果……
③由于获取的哈希结果是BYTE数组,以MD5 32位哈希为例,如果直接以字符串形式或者%x输出都会有问题。因为是4bit对应一个Hex码,所以要进行一下转换,否则:
……直接输出字符串
http://s3/mw690/002S5apNzy6KUq3TPkmf2&690API实现Hash算法(补充SHA256、SHA512)" TITLE="利用Crypto
……直接十六进制输出
http://s8/mw690/002S5apNzy6KUq5Ezgr57&690API实现Hash算法(补充SHA256、SHA512)" TITLE="利用Crypto
好吧,那就处理一下吧……
Step5:
核心代码:
bool CCryptoApiHashDlg::GetHash(int hash_type, CString& hash_result, static CString hash_message)
{
}