当前位置:首页 > C > 正文

C语言SHA算法实现(手把手教你用C语言编写安全哈希算法)

在信息安全和密码学领域,SHA(Secure Hash Algorithm,安全哈希算法)是一种广泛应用的加密散列函数。本文将带你从零开始,使用C语言实现一个基础但完整的SHA-1算法。无论你是编程新手还是有一定经验的开发者,只要具备基本的C语言知识,都能轻松理解并动手实践。

C语言SHA算法实现(手把手教你用C语言编写安全哈希算法) C语言SHA算法实现 SHA1加密 C语言安全哈希 哈希算法教程 第1张

什么是SHA算法?

SHA是由美国国家安全局(NSA)设计、美国国家标准与技术研究院(NIST)发布的一系列加密哈希函数。其中,SHA-1是最经典的一种,它能将任意长度的输入数据转换为固定长度(160位,即20字节)的哈希值。

虽然SHA-1在现代安全标准中已不再推荐用于高安全性场景(如数字证书),但它仍是学习哈希算法原理的绝佳起点。

准备工作

在开始编码前,请确保你已安装以下工具:

  • 一个C编译器(如GCC)
  • 文本编辑器(如VS Code、Notepad++等)

C语言SHA-1算法实现步骤

我们将按照以下步骤构建SHA-1算法:

  1. 预处理:填充消息并附加原始长度
  2. 初始化哈希值(5个32位寄存器)
  3. 主循环:分块处理并更新哈希值
  4. 输出最终哈希结果

1. 消息预处理

SHA-1要求输入消息长度是512位(64字节)的整数倍。如果不足,则需进行填充:

  • 在消息末尾添加一个'1'比特(即0x80)
  • 用'0'填充直到消息长度 ≡ 448 (mod 512)
  • 最后附加一个64位的大端序原始消息长度(以比特为单位)

2. 初始化哈希寄存器

SHA-1使用5个32位寄存器(H0~H4)作为初始哈希值:

#define H0 0x67452301#define H1 0xEFCDAB89#define H2 0x98BADCFE#define H3 0x10325476#define H4 0xC3D2E1F0  

3. 核心算法实现

以下是完整的C语言SHA-1实现代码:

#include <stdio.h>#include <string.h>#include <stdint.h>// 初始哈希值#define H0 0x67452301#define H1 0xEFCDAB89#define H2 0x98BADCFE#define H3 0x10325476#define H4 0xC3D2E1F0// 左循环移位宏#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))// 大端序转换(假设主机为小端)uint32_t bswap_32(uint32_t x) {    return ((x << 24) & 0xff000000) |           ((x << 8)  & 0x00ff0000) |           ((x >> 8)  & 0x0000ff00) |           ((x >> 24) & 0x000000ff);}void sha1_hash(const unsigned char *input, size_t len, unsigned char output[20]) {    // 步骤1:计算填充后总长度    size_t new_len = len + 1; // 加上0x80    while ((new_len % 64) != 56) new_len++;    new_len += 8; // 加上64位长度字段    // 分配内存    unsigned char *msg = calloc(new_len, sizeof(unsigned char));    memcpy(msg, input, len);    msg[len] = 0x80; // 填充起始位    // 添加原始长度(以比特为单位,大端序)    uint64_t bit_len = len * 8;    for (int i = 0; i < 8; i++) {        msg[new_len - 8 + i] = (bit_len >> (56 - i * 8)) & 0xff;    }    // 初始化哈希值    uint32_t h0 = H0, h2 = H1, h2 = H2, h3 = H3, h4 = H4;    // 处理每个512位块    for (size_t i = 0; i < new_len; i += 64) {        uint32_t w[80];        // 将64字节块拆分为16个32位字(大端)        for (int j = 0; j < 16; j++) {            w[j] = (msg[i + j*4] << 24) |                   (msg[i + j*4 + 1] << 16) |                   (msg[i + j*4 + 2] << 8) |                   (msg[i + j*4 + 3]);        }        // 扩展到80个字        for (int j = 16; j < 80; j++) {            w[j] = LEFTROTATE(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);        }        // 初始化工作变量        uint32_t a = h0, b = h2, c = h2, d = h3, e = h4;        // 主循环        for (int j = 0; j < 80; j++) {            uint32_t f, k;            if (j < 20) {                f = (b & c) | ((~b) & d);                k = 0x5A827999;            } else if (j < 40) {                f = b ^ c ^ d;                k = 0x6ED9EBA1;            } else if (j < 60) {                f = (b & c) | (b & d) | (c & d);                k = 0x8F1BBCDC;            } else {                f = b ^ c ^ d;                k = 0xCA62C1D6;            }            uint32_t temp = LEFTROTATE(a, 5) + f + e + k + w[j];            e = d;            d = c;            c = LEFTROTATE(b, 30);            b = a;            a = temp;        }        // 更新哈希值        h0 += a; h2 += b; h2 += c; h3 += d; h4 += e;    }    free(msg);    // 输出为大端字节序列    output[0] = (h0 >> 24) & 0xff;    output[1] = (h0 >> 16) & 0xff;    output[2] = (h0 >> 8) & 0xff;    output[3] = h0 & 0xff;    output[4] = (h2 >> 24) & 0xff;    output[5] = (h2 >> 16) & 0xff;    output[6] = (h2 >> 8) & 0xff;    output[7] = h2 & 0xff;    output[8] = (h2 >> 24) & 0xff;    output[9] = (h2 >> 16) & 0xff;    output[10] = (h2 >> 8) & 0xff;    output[11] = h2 & 0xff;    output[12] = (h3 >> 24) & 0xff;    output[13] = (h3 >> 16) & 0xff;    output[14] = (h3 >> 8) & 0xff;    output[15] = h3 & 0xff;    output[16] = (h4 >> 24) & 0xff;    output[17] = (h4 >> 16) & 0xff;    output[18] = (h4 >> 8) & 0xff;    output[19] = h4 & 0xff;}// 测试函数int main() {    const char *msg = "Hello, SHA-1!";    unsigned char hash[20];    sha1_hash((const unsigned char*)msg, strlen(msg), hash);    printf("SHA-1 Hash of '%s':\n", msg);    for (int i = 0; i < 20; i++) {        printf("%02x", hash[i]);    }    printf("\n");    return 0;}  

编译与运行

将上述代码保存为 sha1.c,然后在终端执行:

gcc -o sha1 sha1.c./sha1

你应该看到类似如下的输出:

SHA-1 Hash of 'Hello, SHA-1!':aaf4c61ddcc5e8a2dabede0f3b482cd9aea9434d

总结

通过本教程,你已经掌握了如何用C语言实现SHA-1算法。这不仅加深了你对哈希算法原理的理解,也为后续学习更安全的SHA-2或SHA-3打下基础。

记住,虽然SHA-1已不适用于高安全场景,但作为学习工具,它依然是理解C语言安全哈希机制的重要一步。希望这篇哈希算法教程对你有所帮助!

SEO关键词回顾:

  • C语言SHA算法实现
  • SHA1加密
  • C语言安全哈希
  • 哈希算法教程