在信息安全和密码学领域,SHA(Secure Hash Algorithm,安全哈希算法)是一种广泛应用的加密散列函数。本文将带你从零开始,使用C语言实现一个基础但完整的SHA-1算法。无论你是编程新手还是有一定经验的开发者,只要具备基本的C语言知识,都能轻松理解并动手实践。
SHA是由美国国家安全局(NSA)设计、美国国家标准与技术研究院(NIST)发布的一系列加密哈希函数。其中,SHA-1是最经典的一种,它能将任意长度的输入数据转换为固定长度(160位,即20字节)的哈希值。
虽然SHA-1在现代安全标准中已不再推荐用于高安全性场景(如数字证书),但它仍是学习哈希算法原理的绝佳起点。
在开始编码前,请确保你已安装以下工具:
我们将按照以下步骤构建SHA-1算法:
SHA-1要求输入消息长度是512位(64字节)的整数倍。如果不足,则需进行填充:
SHA-1使用5个32位寄存器(H0~H4)作为初始哈希值:
#define H0 0x67452301#define H1 0xEFCDAB89#define H2 0x98BADCFE#define H3 0x10325476#define H4 0xC3D2E1F0
以下是完整的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关键词回顾:
本文由主机测评网于2025-12-24发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/20251212175.html