加密哈希函数在确保通信安全、存储数据库中的密码哈希值、验证消息或文件在两个实体之间正确传输等方面有着广泛的应用。其中,MD5(Message Digest Five)是一种广泛使用的算法,它产生一个128位的哈希值,通常表示为32个十六进制数字。MD5是MD4和MD2的后继者,它们都是由Ronald Rivest开发的。另一种基于MD4的哈希算法是SHA-1,它是一种密码学安全的单向哈希算法,产生一个160位的消息摘要(通常表示为40个十六进制数字)。本文提出了一种使用Microsoft CryptoAPI库计算哈希值(SHA1、MD5、MD4和MD2)的C++实现方法。CryptoAPI需要至少Windows XP或Windows Server 2003操作系统。
需要注意的是,MD5和SHA1已经被证明存在弱点。MD5不具备抗碰撞性,并且有其他弱点,这使得它至少在某些安全应用中不适用,包括SSL证书。美国计算机紧急响应团队(US-CERT)得出结论,MD5“应该被认为是密码学上被破坏的,并且不适合进一步使用”。美国国家标准与技术研究院(NIST),SHA1的发布者,也在寻找SHA1的替代品。
为了使用CryptoAPI生成哈希值,必须遵循以下步骤:
实现包括几个模板C++类,它们提供:
这两个类都是用哈希算法参数化的。
template<ALG_ID algorithm> class cryptohash_t;
template<ALG_ID algorithm> class cryptohash_helper_t;
提供了几个typedef,以简化这些模板类的使用。
typedef cryptohash_t<CALG_MD2> md2_t;
typedef cryptohash_t<CALG_MD4> md4_t;
typedef cryptohash_t<CALG_MD5> md5_t;
typedef cryptohash_t<CALG_SHA1> sha1_t;
typedef cryptohash_helper_t<CALG_MD2> md2_helper_t;
typedef cryptohash_helper_t<CALG_MD4> md4_helper_t;
typedef cryptohash_helper_t<CALG_MD5> md5_helper_t;
typedef cryptohash_helper_t<CALG_SHA1> sha1_helper_t;
cryptohash_t具有以下公共接口:
cryptohash_helper_t具有以下公共接口:
在所有以下示例中,可以简单地使用任何提供的哈希类型(md5_t、md4_t、md2_t、sha1_t)或助手类型(md5_helper_t、md4_helper_t、md2_helper_t、sha1_helper_t),无需对示例进行任何其他更改,即可获得相应的结果。
std::string text = "mariusbancila";
std::string digest;
sha1_t hasher;
if (hasher.begin()) {
if (hasher.update((unsigned char*)(text.c_str()), text.length())) {
if (hasher.finalize()) {
digest = hasher.hexdigest();
}
}
}
if (digest.empty())
std::cout << "error code = " << hasher.lasterror().errorCode << ", error message = " << hasher.lasterror().errorMessage << std::endl;
else
std::cout << digest << std::endl;
std::string text1 = "marius";
std::string text2 = "bancila";
std::string digest;
sha1_t hasher;
if (hasher.begin()) {
if (hasher.update((unsigned char*)(text1.c_str()), text1.length())) {
if (hasher.update((unsigned char*)(text2.c_str()), text2.length())) {
if (hasher.finalize()) {
digest = hasher.hexdigest();
}
}
}
}
if (digest.empty())
std::cout << "error code = " << hasher.lasterror().errorCode << ", error message = " << hasher.lasterror().errorMessage << std::endl;
else
std::cout << digest << std::endl;
md5_helper_t hhasher;
std::string digest = hhasher.hexdigesttext("mariusbancila");
if (digest.empty())
std::cout << "error code = " << hhasher.lasterror().errorCode << ", error message = " << hhasher.lasterror().errorMessage << std::endl;
else
std::cout << digest << std::endl;
md5_helper_t hhasher;
std::string digest = hhasher.hexdigestfile("c:\\temp\\sample.png");
if (digest.empty())
std::cout << "error code = " << hhasher.lasterror().errorCode << ", error message = " << hhasher.lasterror().errorMessage << std::endl;
else
std::cout << digest << std::endl;