一、什么是哈希算法,哈希算法有什么作用
什么是哈希算法?
哈希算法(Hash Algorithm)是一类特殊的数学函数,用于将任意长度的输入数据映射为固定长度的输出数据,这个输出通常称为哈希值、消息摘要或指纹。
哈希算法的重要特性
- 固定长度输出:
- 无论输入数据的长度是多少,哈希算法都能产生长度固定的哈希值(例如,SHA-256 的输出始终是 256 位)。
- 不可逆性:
- 雪崩效应:
- 输入的微小变化(如改变一个字母)会导致输出的哈希值发生巨大变化。
- 抗碰撞性:
- 很难找到两个不同的输入数据,经过哈希后得到相同的输出(称为“哈希碰撞”)。
- 快速计算:
- 哈希算法的计划使其可以或许快速天生哈希值,适合大规模数据处理惩罚。
哈希算法的作用
哈希算法在当代计算机系统中具有广泛的应用,重要体如今以下几个方面:
1. 数据完整性验证
哈希算法可以用来检测数据在传输或存储过程中是否被篡改。
- 在传输数据之宿世成哈希值,并随数据一起发送。
- 吸收方重新计算哈希值并与发送的哈希值对比,如果一致则数据未被篡改。
应用场景:
- 文件校验(例如 MD5 或 SHA-256 校验)。
- 软件分发中的校验码。
2. 暗码存储
用户暗码在存储时不会直接保存原文,而是保存经过哈希处理惩罚的值(通常还会加盐)。
- 用户登录时输入的暗码会再次哈希并与存储的哈希值对比,以验证身份。
- 纵然存储系统被攻破,也难以还原用户暗码。
常用算法:
- SHA-2 家族(SHA-256)。
- bcrypt、scrypt(专为暗码存储计划)。
3. 数字签名和数字证书
哈希算法用于天生文档的唯一摘要,用于签名和验证:
- 数字签名:
- 文档哈希值由私钥加密,吸收方用公钥解密验证,确保文档未被篡改。
- 数字证书:
- 通过哈希算法和证书颁发机构签名,确认网站或软件的可信性。
4. 数据索引
哈希算法被广泛应用于高效的数据查找和索引。
- 哈希表(Hash Table):
- 将数据通过哈希函数映射到特定的存储位置,实现快速查找。
- 缓存系统:
5. 区块链和加密货币
在区块链中,哈希算法用于确保数据完整性和天生区块链结构。
- 区块链:
- 每个区块都包罗前一个区块的哈希值,形成链式结构,确保篡改后无法通过验证。
- 加密货币挖矿:
- 利用工作量证明(PoW)机制,矿工必要找到满足特定条件的哈希值。
6. 消息认证与密钥验证
哈希算法联合密钥可用于天生消息认证码(MAC),确保消息泉源和内容未被篡改。
7. 文件去重
在文件管理系统中,利用哈希值检测重复文件,由于相同的文件会天生相同的哈希值。
常见哈希算法
- MD5(Message Digest 5):
- 输出长度:128 位。
- 特点:速度快,但抗碰撞性差,已被镌汰。
- SHA-1(Secure Hash Algorithm 1):
- 输出长度:160 位。
- 特点:更安全,但已被发现存在漏洞,逐渐镌汰。
- SHA-2(SHA-224、SHA-256、SHA-384、SHA-512):
- 输出长度:224 至 512 位。
- 特点:安全性高,广泛利用。
- SHA-3(基于 Keccak 算法):
- 输出长度:224 至 512 位。
- 特点:最新尺度,安全性更高。
- 其他算法:
总结
哈希算法是当代信息技术中的核心工具,其作用涵盖了数据完整性验证、安全存储、加密验证、高效索引等多个范畴。选择合适的哈希算法取决于详细的应用场景及安全性需求。
二、各类哈希算法的代码实现
以下是利用 OpenSSL 实现常见哈希算法的 C 代码示例,包括 MD5、SHA-1、SHA-2 和 SHA-3 的实现。
完整示例代码
- #include <openssl/evp.h>
- #include <stdio.h>
- #include <string.h>
- void compute_hash(const char *algorithm, const char *data) {
- // 初始化 OpenSSL 哈希上下文
- EVP_MD_CTX *ctx = EVP_MD_CTX_new();
- const EVP_MD *md = EVP_get_digestbyname(algorithm);
- if (md == NULL) {
- printf("Unsupported algorithm: %s\n", algorithm);
- EVP_MD_CTX_free(ctx);
- return;
- }
- // 初始化哈希计算
- EVP_DigestInit_ex(ctx, md, NULL);
- // 提供输入数据
- EVP_DigestUpdate(ctx, data, strlen(data));
- // 获取哈希值
- unsigned char hash[EVP_MAX_MD_SIZE];
- unsigned int hash_len = 0;
- EVP_DigestFinal_ex(ctx, hash, &hash_len);
- // 打印哈希值
- printf("%s hash of "%s": ", algorithm, data);
- for (unsigned int i = 0; i < hash_len; i++) {
- printf("%02x", hash[i]);
- }
- printf("\n");
- // 释放上下文
- EVP_MD_CTX_free(ctx);
- }
- int main() {
- const char *data = "Hello, OpenSSL!";
- // 计算并打印不同算法的哈希值
- compute_hash("MD5", data); // MD5
- compute_hash("SHA1", data); // SHA-1
- compute_hash("SHA224", data); // SHA-224
- compute_hash("SHA256", data); // SHA-256
- compute_hash("SHA384", data); // SHA-384
- compute_hash("SHA512", data); // SHA-512
- compute_hash("SHA3-256", data); // SHA-3 (256 位)
- compute_hash("SHA3-512", data); // SHA-3 (512 位)
- return 0;
- }
复制代码 代码说明
- 核心函数:compute_hash
- 输入参数:
- algorithm:指定哈希算法名称,例如 MD5、SHA256、SHA3-256。
- data:要计算哈希值的输入数据。
- 功能:
- 利用 OpenSSL 的 EVP 接口计算哈希值。
- 打印效果。
- 支持的算法名称
- MD5: "MD5"
- SHA-1: "SHA1"
- SHA-2: "SHA224", "SHA256", "SHA384", "SHA512"
- SHA-3: "SHA3-224", "SHA3-256", "SHA3-384", "SHA3-512"
- 重要步骤
- 初始化哈希上下文:EVP_MD_CTX_new。
- 获取哈希算法:EVP_get_digestbyname。
- 提供输入数据:EVP_DigestUpdate。
- 计算哈希值:EVP_DigestFinal_ex。
- 安全性
- 保举在安全场景中利用 SHA-2 或 SHA-3,避免利用 MD5 和 SHA-1。
运行效果:
三、利用命令行哈希算法
利用 OpenSSL 命令行工具,可以非常方便地计算各种哈希值,包括 MD5、SHA-1、SHA-2 和 SHA-3 等。以下是详细的操作方法:
1. 根本格式
- openssl dgst -<算法名称> <文件名>
复制代码 2. 常见哈希算法命令
(1)MD5
计算文件的 MD5 哈希值:
- openssl dgst -md5 file.txt
复制代码 输出示例:
- MD5(file.txt)= 098f6bcd4621d373cade4e832627b4f6
复制代码 (2)SHA-1
计算文件的 SHA-1 哈希值:
- openssl dgst -sha1 file.txt
复制代码 输出示例:
- SHA1(file.txt)= 356a192b7913b04c54574d18c28d46e6395428ab
复制代码 (3)SHA-2 系列
- SHA-224:
- openssl dgst -sha224 file.txt
复制代码 - SHA-256:
- openssl dgst -sha256 file.txt
复制代码 - SHA-384:
- openssl dgst -sha384 file.txt
复制代码 - SHA-512:
- openssl dgst -sha512 file.txt
复制代码 (4)SHA-3 系列
必要支持 OpenSSL 1.1.1 或更高版本。
- SHA3-224:
- openssl dgst -sha3-224 file.txt
复制代码 - SHA3-256:
- openssl dgst -sha3-256 file.txt
复制代码 - SHA3-384:
- openssl dgst -sha3-384 file.txt
复制代码 - SHA3-512:
- openssl dgst -sha3-512 file.txt
复制代码 3. 计算字符串的哈希值
可以通过 echo 命令和管道计算字符串的哈希值:
(1)计算字符串的 MD5
- echo -n "Hello, OpenSSL!" | openssl dgst -md5
复制代码 输出示例:
- (stdin)= 3a01be9d860c380a1df0df857d17ff86
复制代码 (2)计算字符串的 SHA-256
- echo -n "Hello, OpenSSL!" | openssl dgst -sha256
复制代码 输出示例:
- (stdin)= c38c1d067d2c4d99925160a8e53947e68890a5a4b6f76af71c818c48b995f456
复制代码 (3)计算字符串的 SHA3-512
- echo -n "Hello, OpenSSL!" | openssl dgst -sha3-512
复制代码 输出示例:
- (stdin)= a194121050c3cfa2fb23aefc46f057b7200a48602e8bfc8e8616a60a81df91c60635651c1f67dc75e3a0271da36563585b2a91673ae0438efb4c3af5bd529554
复制代码 注意:
- -n 参数用于避免 echo 命令在字符串末尾添加换行符。
- | 用于将字符串作为输入传递给 openssl dgst。
4. 其他选项
(1)输出二进制哈希值
如果必要二进制格式的哈希值,可以利用 -binary:
- openssl dgst -sha256 -binary file.txt > hash.bin
复制代码 (2)指定输出为十六进制
默认输出为十六进制格式,但你可以显式指定:
- openssl dgst -sha256 -hex file.txt
复制代码 (3)验证文件完整性
可以通过哈希值验证文件是否被篡改。例如:
- 计算文件哈希值并保存:
- openssl dgst -sha256 file.txt
- > file.hash
复制代码 - 验证文件:
- openssl dgst -sha256 -verify file.hash file.txt
复制代码 5. 示例操作
假设有一个文件 example.txt,内容为 Hello, OpenSSL!。
计算 MD5
- openssl dgst -md5 example.txt
复制代码 输出:
- MD5(example.txt)= 3a01be9d860c380a1df0df857d17ff86
复制代码 计算 SHA-256
- openssl dgst -sha256 example.txt
复制代码 输出:
- SHA256(example.txt)= c38c1d067d2c4d99925160a8e53947e68890a5a4b6f76af71c818c48b995f456
复制代码 计算 SHA3-512
- openssl dgst -sha3-512 example.txt
复制代码 输出:
- SHA3-512(example.txt)= a194121050c3cfa2fb23aefc46f057b7200a48602e8bfc8e8616a60a81df91c60635651c1f67dc75e3a0271da36563585b2a91673ae0438efb4c3af5bd529554
复制代码 通过这些命令,你可以快速计算文件或字符串的哈希值,适用于验证数据完整性和加密需求。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |