CSHA1 - SHA-1 哈希算法的 C++ 类实现






4.89/5 (70投票s)
CSHA1 - SHA-1 哈希算法的 C++ 类实现
目录
安全散列算法 SHA-1 描述
安全散列算法 SHA-1 是一种 密码学安全单向哈希算法。它由 NIST (美国国家标准与技术研究院) 和 NSA (美国国家安全局) 设计。SHA-1 基于 MIT 的 Ronald L. Rivest 设计的 Message Digest MD4 算法原理。
嗯,我想我不用解释你可以用密码学哈希算法做什么了。例如,你可以看看 这篇 CodeProject 文章 (CMD5 类) 来了解你可以用这类算法做什么。
关于 SHA-1 的更多信息,请参阅参考文献 [1] 和 [2]。
CSHA1 类描述
CSHA1
类是 SHA-1 哈希算法的一个易于使用的类。
如果你想测试你的类实现是否正常工作,请尝试演示 zip 文件中“TestVectors”目录里的测试向量。你可以在 CSHA1
类的头文件中找到正确的哈希值。
CSHA1
类的成员
-
void Reset();
此成员函数重置类。当你多次使用
CSHA1
时,必须调用此方法。此方法在类的构造函数和析构函数中被自动调用,所以如果你只哈希一个数据流,你不需要手动调用Reset()
。 -
void Update(const UINT_8* pbData, UINT_32 uLen);
使用此方法通过数据流进行哈希。数据在
pbData
中,字节数为uLen
。 -
bool HashFile(const TCHAR* tszFileName);
此方法将文件内容哈希到当前状态。如果哈希成功,该方法返回
true
,否则返回false
。如果你使用此成员函数,你不需要调用Update(...)
方法。在调用HashFile(...)
后,你应该立即调用Final()
方法。在使用ReportHash(...)
和GetHash(...)
方法获取文件消息摘要之前,你必须调用Final()
。 -
void Final();
当你已哈希完所有需要哈希的数据后,请调用此方法。这将计算最终的 SHA-1 消息摘要,因此在使用
ReportHash(...)
和GetHash(...)
之前必须调用此方法。 -
bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const;
调用
Final
方法后,你可以使用此方法获取消息摘要。结果将作为字符串存储在tszReport
中。uReportType
的有效格式类型为REPORT_HEX
、REPORT_DIGIT
和REPORT_HEX_SHORT
。如果你使用REPORT_HEX
,返回的字符串看起来像5F A9 FB 34
...,使用REPORT_DIGIT
时,此方法以129 67 5 98
... 的形式返回消息摘要。REPORT_HEX_SHORT
与REPORT_HEX
相同,只是没有分隔符空格。 -
bool GetHash(UINT_8* pbDest20) const;
如果你不想通过
ReportHash
以预格式化字符串的形式获取哈希值,可以使用此方法。此方法将最终消息摘要 (先调用Final
!) 复制到pbDest20
。pbDest20
必须至少能容纳 20 字节 (SHA-1 会产生一个 160 位/20 字节的哈希值)。
哈希二进制数据和字符串
CSHA1 sha1;
sha1.Update(string0, strlen(string0));
sha1.Update(string1, strlen(string1));
sha1.Update(binary2, uSizeOfBufferBinary2);
sha1.Update(binary3, uSizeOfBufferBinary3);
sha1.Final();
sha1.ReportHash(szReport, CSHA1::REPORT_HEX_SHORT);
// or
sha1.GetHash(binaryArray);
我现在将对上面的示例逐行注释。
首先声明 CSHA1
类的一个实例
CSHA1 sha1;
现在像这样哈希数据
sha1.Update((UINT_8*)szString, strlen(szString));
你可以根据需要多次调用此方法。
当你哈希完所有数据后,调用 Final()
成员函数
sha1.Final();
如果你想获取最终消息摘要作为预格式化字符串,请使用此方法
sha1.ReportHash(szReport, CSHA1::REPORT_HEX_SHORT);
如果你想以“原始格式”获取最终消息摘要
sha1.GetHash(binaryArray); // Get the raw message digest bytes
哈希文件
哈希文件与哈希字符串和二进制数据的过程相同,但不是使用 Update
方法,而是使用类的 HashFile
成员函数。
有关更多注释,请参阅上面的字符串/二进制数据哈希示例。
CSHA1 sha1;
sha1.HashFile("TheFile.cpp"); // Hash in the contents of the file
// 'TheFile.cpp'
sha1.Final();
sha1.ReportHash(szReport, CSHA1::REPORT_HEX); // Get final hash as
// pre-formatted string
// or
sha1.GetHash(binaryArray); // Get the raw message digest bytes to a
// temporary buffer
参考文献
[1] RFC 3174: US Secure Hash Algorithm 1 (SHA1)。
[2] Bruce Schneier,Applied Cryptography,第 442-445 页。
版本历史
- 版本 2.1 - 2012-06-19
- 析构函数 (重置内部变量) 现在仅在定义了
SHA1_WIPE_VARIABLES
(这是默认设置) 时实现。 - 包含 GUID 以重命名包含保护。
- 演示应用程序现在使用 C++/STL 对象和函数。
- Unicode 构建的演示应用程序现在输出字符串的 ANSI 和 Unicode 表示形式的哈希值。
- 其他各种演示应用程序改进。
- 析构函数 (重置内部变量) 现在仅在定义了
- 版本 2.0 - 2012-06-14
- 添加了 '
limits.h
' 包含。 - 为兼容性重命名了包含保护和宏 (以下划线开头的名称是保留的)。
- 添加了 '
- 版本 1.9 - 2011-11-10
- 添加了 Unicode 测试向量。
- 改进了使用
HashFile
方法哈希大于 4 GB 的文件的支持。 - 改进了文件哈希性能 (通过使用更大的缓冲区)。
- 禁用了不必要的编译器警告。
- 内部变量现在为
private
。
- 版本 1.8 - 2009-03-16
- 将项目文件转换为 Visual Studio 2008 格式。
- 为
HashFile
实用函数添加了 Unicode 支持。 - 添加了使用
HashFile
方法哈希大于 2 GB 的文件的支持。 HashFile
现在返回错误代码,而不是将错误消息复制到输出缓冲区。GetHash
现在返回错误代码并验证输入参数。- 添加了
ReportHashStl
STL 实用函数。 - 添加了
REPORT_HEX_SHORT
报告模式。 - 改进了测试程序的 Linux 兼容性。
- 版本 1.7 - 2006-12-21
- 修复了在使用 Borland C Builder 编译时出现的缓冲区下溢警告 (感谢 Rex Bloom 和 Tim Gallagher 提供补丁)。
- 破坏性更改:
ReportHash
将最终哈希值写入缓冲区的开头,即它不再将其附加到字符串末尾。 - 使某些函数参数为
const
。 - 将 Visual Studio 2005 项目文件添加到演示项目中。
- 版本 1.6 - 2005-02-07
- 你可以在文件中设置字节序,无需再修改
CSHA1
类的头文件。 - 支持对齐数据。
- 使支持/编译实用函数 (
ReportHash
和HashFile
) 可选 (在字节计数受限的环境中很有用,例如嵌入式环境)。 - 感谢 Howard Kapustein 提供补丁。
- 你可以在文件中设置字节序,无需再修改
- 版本 1.5 - 2005-01-01
- 增加了对 64 位编译器的兼容性。
- 使变量擦除成为可选 (定义
SHA1_WIPE_VARIABLES
)。 - 移除了不必要的变量初始化。
- 为 Microsoft 编译器改进了
ROL32
(使用_rotl
)。
- 版本 1.4 - 2004-07-22
CSHA1
现在可以在 Mac OS X 下使用 GCC 3.3 正常编译 (感谢 Larry Hastings)。
- 版本 1.3 - 2003-08-17
- 修复了一个小的内存错误,并将一个缓冲区数组设为类成员,以确保在同时使用多个
CSHA1
类实例时能正常工作。
- 修复了一个小的内存错误,并将一个缓冲区数组设为类成员,以确保在同时使用多个
- 版本 1.2 - 2002-11-16
- Borland C++ 编译器在使用
sprintf
进行字符串加法时似乎存在问题。修复了导致摘要报告函数无法正常工作的错误。CSHA1
现在兼容 Borland。
- Borland C++ 编译器在使用
- 版本 1.1 - 2002-10-11
- 移除了两个不必要的头文件包含,并将
BOOL
更改为bool
。修复了网页内容中的一些小错误。
- 移除了两个不必要的头文件包含,并将
- 版本 1.0 - 2002-06-20
- 首次正式发布。
就是这样!祝你哈希愉快!