MD5加密算法的基础理论与实现过程

MD5加密算法的基础理论与实现过程

一、基础理论

MD5(Message-Digest Algorithm 5)是一种广泛使用的加密算法,用于产生数据的散列值(hash value)。MD5算法将任意长度的数据作为输入,经过一系列的处理,输出一个128位(32个字符)的散列值。

MD5算法的实现过程如下:

  1. 填充数据:将输入数据的位数填充至512的倍数,填充的方法是在数据的末尾添加一个1和若干个0,直到数据的长度满足要求。
  2. 添加长度信息:在填充后的数据末尾添加原始数据的长度,以64位表示。
  3. 初始化MD5寄存器:MD5算法使用4个32位寄存器(A、B、C、D)来存储中间结果,这些寄存器会在算法的不同阶段更新。
  4. 初始化常量:MD5算法使用一个常量数组来进行循环运算,这些常量在算法的每一轮中都会使用到。
  5. 分组处理:将填充后的数据分成若干个512位的分组,每个分组再分成16个32位的子分组。
  6. 循环运算:对每个分组进行4轮循环运算,每轮都会对寄存器进行更新操作,最终得到一个128位的散列值。
  7. 输出结果:将4个寄存器中的内容按照A、B、C、D的顺序连接起来,得到最终的128位散列值。

MD5算法的特点是快速、简单,但由于其设计存在一些安全漏洞,已经被广泛认为不安全。在实际应用中,建议使用更安全的哈希算法如SHA-256来代替MD5算法。

二、代码实现(c语言)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define LEFTROTATE(x, c) (((x) << (c)) | ((x) >> (32 - (c))))

// MD5算法中使用的常量
const uint32_t k[] = {
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

// 初始化MD5寄存器的值
const uint32_t initial_h[] = {
    0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476
};

/**
 * @function name:	MD5
 * @brief  MD5核心算法
 * @param @uint8_t *data
          @size_t size_t len
          @uint64_t bitlen
 * @retval 函数返回类型说明
 * @date 2024/06/12
 * @version 1.0 :版本
 * @note   补充 注意 说明
 */
// 对数据进行填充
void pad_data(uint8_t *data, size_t len, uint64_t bitlen) {
    // 填充一个1
    data[len++] = 0x80;

    // 填充0直到满足64字节的倍数
    while (len % 64 != 56) {
        data[len++] = 0x00;
    }

    // 在末尾追加数据长度(64位表示)
    for (int i = 0; i < 8; ++i) {
        data[len++] = (bitlen >> (i * 8)) & 0xFF;
    }
}

/**
 * @function name:	MD5
 * @brief  MD5核心算法
 * @param @uint8_t *initial_msg
          @size_t initial_len
          @uint32_t *hash
 * @retval 函数返回类型说明
 * @date 2024/06/12
 * @version 1.0 :版本
 * @note   补充 注意 说明
 */
// MD5算法核心函数
void md5(uint8_t *initial_msg, size_t initial_len, uint32_t *hash) {
    uint8_t *msg = NULL;
    size_t new_len, offset;
    uint32_t w[64];
    uint32_t a, b, c, d, i, j, t;

    // 初始化寄存器
    hash[0] = initial_h[0];
    hash[1] = initial_h[1];
    hash[2] = initial_h[2];
    hash[3] = initial_h[3];

    // 对数据进行填充
    new_len = initial_len * 8 + 1 + 64;
    msg = (uint8_t*)malloc(new_len);
    memcpy(msg, initial_msg, initial_len);
    pad_data(msg, initial_len, initial_len * 8);

    // 处理数据
    for(offset = 0; offset < new_len; offset += 64) {
        // 将分组的数据填充到w数组中
        for (i = 0; i < 16; ++i) {
            w[i] = (msg[offset + i * 4 + 0] << 24) |
                   (msg[offset + i * 4 + 1] << 16) |
                   (msg[offset + i * 4 + 2] << 8) |
                   (msg[offset + i * 4 + 3]);
        }
        for (i = 16; i < 64; ++i) {
            w[i] = w[i-16] + LEFTROTATE(w[i-15], 7) + w[i-7] + LEFTROTATE(w[i-2], 15);
        }

        // 初始化临时变量
        a = hash[0];
        b = hash[1];
        c = hash[2];
        d = hash[3];

        // 主循环
        for (i = 0; i < 64; ++i) {
            if (i < 16) {
                t = (b & c) | ((~b) & d);
                j = i;
            } else if (i < 32) {
                t = (d & b) | ((~d) & c);
                j = (5 * i + 1) % 16;
            } else if (i < 48) {
                t = b ^ c ^ d;
                j = (3 * i + 5) % 16;
            } else {
                t = c ^ (b | (~d));
                j = (7 * i) % 16;
            }

            t = t + a + k[i] + w[j];
            a = d;
            d = c;
            c = b;
            b = b + LEFTROTATE(t, 12);
        }

        // 更新寄存器值
        hash[0] += a;
        hash[1] += b;
        hash[2] += c;
        hash[3] += d;
    }

    // 释放内存
    free(msg);
}

int main() {
    // 示例数据
    uint8_t initial_msg[] = "Hello, world!";
    size_t initial_len = strlen((char*)initial_msg);
    uint32_t hash[4];

    // 计算MD5散列值
    md5(initial_msg, initial_len, hash);
    printf("MD5 散列值为: ");
    for (int i = 0; i < 4; ++i) {
        printf("%02x", hash[i]);
    }
    printf("\n");

    return 0;
}

posted @ 2024-06-12 19:59  Zeratul$$$  阅读(327)  评论(0)    收藏  举报