高阶哈希算法

SHA-256简介

SHA-256 是 **SHA-2(Secure Hash Algorithm 2)**家族中的一种哈希算法,由美国国家安全局设计,并于 2001 年发布。它能够将任意长度的数据映射为一个固定长度256 位,即 32 字节的哈希值,通常以 64 个十六进制字符的形式表示。SHA-256 被广泛用于数据完整性验证、数字签名、区块链等领。

SHA-256 的特点

  1. 固定输出长度 :
    • SHA-256 生成的哈希值始终是 256 位(32 字节)。
  2. 不可逆性 :
    • 从哈希值无法反推出原始数据。
  3. 雪崩效应 :
    • 输入数据的微小变化会导致输出哈希值的巨大变化。
  4. 抗碰撞性 :
    • 设计上极难找到两个不同的输入生成相同的哈希值。
  5. 高效性 :
    • 计算速度快,适合处理大量数据。
  6. 安全性 :
    • 目前尚未发现有效的攻击方法,被广泛认为是安全的。

SHA-256 的应用场景

  1. 数据完整性验证 :
    • 通过比较文件的 SHA-256 值,可以验证文件是否被篡改。
  2. 数字签名 :
    • 用于生成数据的唯一标识,确保数据的真实性和完整性。
  3. 区块链 :
    • 比特币和其他加密货币使用 SHA-256 进行区块哈希计算。
  4. 密码存储 :
    • 用于存储用户密码的哈希值(通常与盐值结合使用)。
  5. 证书和密钥 :
    • 用于生成 SSL/TLS 证书和密钥。

SHA-256 的工作原理

SHA-256 的计算过程可以分为以下几个步骤:

1. 填充数据
  • 将输入数据的长度填充至 512 位(64 字节)的倍数。
  • 填充方式:在数据末尾添加一个 1,然后添加若干个 0,最后添加一个 64 位的整数,表示原始数据的长度。
2. 初始化哈希值
  • SHA-256 使用 8 个 32 位的状态变量(A, B, C, D, E, F, G, H),初始值为以下常量:

    ini 复制代码
    A = 0x6A09E667
    B = 0xBB67AE85
    C = 0x3C6EF372
    D = 0xA54FF53A
    E = 0x510E527F
    F = 0x9B05688C
    G = 0x1F83D9AB
    H = 0x5BE0CD19
3. 分块处理
  • 将填充后的数据分割成若干个 512 位(64 字节)的块。
  • 对每个块进行 64 轮处理。
4. 64 轮变换
  • 每轮使用以下非线性函数和常量:
    • Ch : Ch(x, y, z) = (x & y) ^ (~x & z)
    • Maj : Maj(x, y, z) = (x & y) ^ (x & z) ^ (y & z)
    • Σ0 : Σ0(x) = (x >>> 2) ^ (x >>> 13) ^ (x >>> 22)
    • Σ1 : Σ1(x) = (x >>> 6) ^ (x >>> 11) ^ (x >>> 25)
    • 常量表:使用 64 个预定义的常量值。
5. 更新哈希值
  • 每轮处理后,更新状态变量(A, B, C, D, E, F, G, H)。
6. 输出哈希值
  • 将最终的 8 个状态变量(A, B, C, D, E, F, G, H)按大端序拼接,生成 256 位的哈希值。

SHA-256 的伪代码

以下是 SHA-256 算法的简化伪代码:

plaintext 复制代码
Input: 数据 data
Output: 256 位的哈希值

1. 填充数据:
   - 在 data 末尾添加 1 和若干个 0,使其长度 ≡ 448 mod 512
   - 在末尾添加 64 位的原始数据长度

2. 初始化哈希值:
   A = 0x6A09E667
   B = 0xBB67AE85
   C = 0x3C6EF372
   D = 0xA54FF53A
   E = 0x510E527F
   F = 0x9B05688C
   G = 0x1F83D9AB
   H = 0x5BE0CD19

3. 对每个 512 位块进行处理:
   - 将块分割为 16 个 32 位字
   - 扩展为 64 个 32 位字
   - 进行 64 轮变换

4. 输出哈希值:
   - 将 A, B, C, D, E, F, G, H 按大端序拼接
   - 转换为 64 个十六进制字符

SHA-256 的代码实现

以下是 SHA-256 的 C 语言实现的核心部分:

c 复制代码
#include <stdio.h>
#include <string.h>
#include <stdint.h>

// SHA-256 状态变量
typedef struct {
    uint32_t state[8];  // A, B, C, D, E, F, G, H
    uint8_t buffer[64]; // 缓冲区
    uint64_t length;    // 数据长度
} SHA256_CTX;

// 初始化 SHA-256 上下文
void SHA256_Init(SHA256_CTX *ctx) {
    ctx->state[0] = 0x6A09E667;
    ctx->state[1] = 0xBB67AE85;
    ctx->state[2] = 0x3C6EF372;
    ctx->state[3] = 0xA54FF53A;
    ctx->state[4] = 0x510E527F;
    ctx->state[5] = 0x9B05688C;
    ctx->state[6] = 0x1F83D9AB;
    ctx->state[7] = 0x5BE0CD19;
    ctx->length = 0;
}

// 更新 SHA-256 上下文
void SHA256_Update(SHA256_CTX *ctx, const uint8_t *data, size_t len) {
    // 处理数据块
}

// 生成最终的 SHA-256 哈希值
void SHA256_Final(SHA256_CTX *ctx, uint8_t digest[32]) {
    // 填充数据并生成哈希值
}

// 计算数据的 SHA-256 值
void SHA256(const uint8_t *data, size_t len, uint8_t digest[32]) {
    SHA256_CTX ctx;
    SHA256_Init(&ctx);
    SHA256_Update(&ctx, data, len);
    SHA256_Final(&ctx, digest);
}

SHA-256 的优缺点

优点:
  1. 安全性高:抗碰撞性强,尚未发现有效的攻击方法。
  2. 固定输出长度:便于存储和比较。
  3. 高效性:计算速度快,适合处理大量数据。
缺点:
  1. 计算资源消耗较大:相比 MD5,SHA-256 的计算开销更大。
  2. 不适合密码存储:虽然安全,但通常需要与盐值结合使用。

以下是 MD5 和 SHA-256 的对比表格:

特性 MD5 SHA-256
全称 Message Digest Algorithm 5 Secure Hash Algorithm 256-bit
设计者 Ronald Rivest 美国国家安全局(NSA)
发布时间 1991 2001
输出长度 128 位(16 字节) 256 位(32 字节)
哈希值表示 32 个十六进制字符 64 个十六进制字符
不可逆性 是 是
雪崩效应 是 是
抗碰撞性 弱(存在碰撞风险) 强(尚未发现有效碰撞攻击)
计算速度 快 较慢(比 MD5 慢)
安全性 不安全(已被证明存在碰撞漏洞) 安全(目前无有效攻击方法)
应用场景 文件校验、数据去重(不推荐用于安全场景) 文件校验、数字签名、区块链、密码存储
填充方式 填充至 448 位(56 字节)的倍数 填充至 512 位(64 字节)的倍数
状态变量 4 个(A, B, C, D) 8 个(A, B, C, D, E, F, G, H)
处理轮数 4 轮(每轮 16 次操作) 64 轮
非线性函数 F, G, H, I Ch, Maj, Σ0, Σ1
常量表 无 64 个预定义常量
初始值 A=0x67452301, B=0xEFCDAB89, C=0x98BADCFE, D=0x10325476 A=0x6A09E667, B=0xBB67AE85, C=0x3C6EF372, D=0xA54FF53A, E=0x510E527F, F=0x9B05688C, G=0x1F83D9AB, H=0x5BE0CD19
推荐使用场景 非安全性场景(如文件校验) 安全性要求高的场景(如数字签名、区块链)
  • MD5:计算速度快,但安全性不足,已被证明存在碰撞漏洞,不推荐用于安全性要求高的场景。
  • SHA-256:安全性高,抗碰撞性强,是目前广泛使用的哈希算法,适合安全性要求高的场景。
相关推荐
信奥卷王10 小时前
[GESP202609 六级] 分树规划
算法
夏幻灵10 小时前
LeetCode 21:合并两个有序链表——双指针与哑节点详解
算法·leetcode·链表
徐小黑ACG12 小时前
Golang 基础05 结构体struct
开发语言·算法·golang
Navigator_Z12 小时前
LeetCode //C - 1286. Iterator for Combination
c语言·算法·leetcode
北极有牛13 小时前
cpp学习笔记--常量指针
java·开发语言·算法
GPU实战笔记13 小时前
云端 GPU 训练的账户余额提醒:它能说明什么,不能说明什么?
深度学习·算法·成本管理·gpu云计算·云端训练
浮链序13 小时前
怎么证明"你这个模型是偷我的"——把蒸馏变成取证工具
算法·安全·llm
小O的算法实验室13 小时前
IEEE TMC,面向异构物联网的多目标量子行为拓扑优化算法
算法
liliangcsdn14 小时前
派息率指标的应用探索和分析
大数据·算法