`
hzy3774
  • 浏览: 993147 次
  • 性别: Icon_minigender_1
  • 来自: 珠海
社区版块
存档分类
最新评论

使用MD5算法验证文件完整性或密码正确性

 
阅读更多

          MD5即Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。是计算机广泛使用的杂凑算法之一(又译摘要算法、哈希算法),主流编程语言普遍已有MD5实现。

            将数据(如汉字)运算为另一固定长度值,是杂凑算法的基础原理,MD5的前身有MD2、MD3和MD4。

            MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。

          MD5在实际应用中通常有两种用法,一种是计算一个字符串的MD5值,常用于密码相关的操作;另一种是用于计算一个文件的MD5值,一般用于网络传输中验证文件是否出错。

        下面是C语言的MD5计算程序,来自Stardict,网上流行的代码都大同小异:

 

md5.h

 

#ifndef MD5_H
#define MD5_H

#ifdef __cplusplus
extern "C"
{
#endif                          /* __cplusplus */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif

#ifdef HAVE_STDINT_H
	#include <stdint.h>
	typedef uint32_t uint32;
#else
	/* A.Leo.: this wont work on 16 bits platforms ;) */
	typedef unsigned uint32;
#endif

#define MD5_FILE_BUFFER_LEN 1024

struct MD5Context {
	uint32 buf[4];
	uint32 bits[2];
	unsigned char in[64];
};

void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf,
	       unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
void MD5Transform(uint32 buf[4], uint32 const in[16]);

int getBytesMD5(const unsigned char* src, unsigned int length, char* md5);
int getStringMD5(const char* src, char* md5);
int getFileMD5(const char* path, char* md5);

/*
 * This is needed to make RSAREF happy on some MS-DOS compilers.
 */
typedef struct MD5Context MD5_CTX;

#ifdef __cplusplus
}
#endif                          /* __cplusplus */

#endif /* !MD5_H */

 源文件:

md5.c

 

#include <string.h>		/* for memcpy() */
#include <stdio.h>
#include "md5.h"

#ifndef HIGHFIRST
#define byteReverse(buf, len)	/* Nothing */
#else
void byteReverse(unsigned char *buf, unsigned longs);

#ifndef ASM_MD5
/*
 * Note: this code is harmless on little-endian machines.
 */
void byteReverse(unsigned char *buf, unsigned longs)
{
	uint32 t;
	do {
		t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
		((unsigned) buf[1] << 8 | buf[0]);
		*(uint32 *) buf = t;
		buf += 4;
	}while (--longs);
}
#endif
#endif

static void putu32(uint32 data, unsigned char *addr) {
	addr[0] = (unsigned char) data;
	addr[1] = (unsigned char) (data >> 8);
	addr[2] = (unsigned char) (data >> 16);
	addr[3] = (unsigned char) (data >> 24);
}

/*
 * Start MD5 accumulation.  Set bit count to 0 and buffer to mysterious
 * initialization constants.
 */
void MD5Init(struct MD5Context *ctx) {
	ctx->buf[0] = 0x67452301;
	ctx->buf[1] = 0xefcdab89;
	ctx->buf[2] = 0x98badcfe;
	ctx->buf[3] = 0x10325476;

	ctx->bits[0] = 0;
	ctx->bits[1] = 0;
}

/*
 * Update context to reflect the concatenation of another buffer full
 * of bytes.
 */
void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len) {
	uint32 t;

	/* Update bitcount */

	t = ctx->bits[0];
	if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
		ctx->bits[1]++; /* Carry from low to high */
	ctx->bits[1] += len >> 29;

	t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */

	/* Handle any leading odd-sized chunks */

	if (t) {
		unsigned char *p = (unsigned char *) ctx->in + t;

		t = 64 - t;
		if (len < t) {
			memcpy(p, buf, len);
			return;
		}
		memcpy(p, buf, t);
		byteReverse(ctx->in, 16);
		MD5Transform(ctx->buf, (uint32 *) ctx->in);
		buf += t;
		len -= t;
	}
	/* Process data in 64-byte chunks */

	while (len >= 64) {
		memcpy(ctx->in, buf, 64);
		byteReverse(ctx->in, 16);
		MD5Transform(ctx->buf, (uint32 *) ctx->in);
		buf += 64;
		len -= 64;
	}

	/* Handle any remaining bytes of data. */

	memcpy(ctx->in, buf, len);
}

/*
 * Final wrapup - pad to 64-byte boundary with the bit pattern 
 * 1 0* (64-bit count of bits processed, MSB-first)
 */
void MD5Final(unsigned char digest[16], struct MD5Context *ctx) {
	unsigned count;
	unsigned char *p;

	/* Compute number of bytes mod 64 */
	count = (ctx->bits[0] >> 3) & 0x3F;

	/* Set the first char of padding to 0x80.  This is safe since there is
	 always at least one byte free */
	p = ctx->in + count;
	*p++ = 0x80;

	/* Bytes of padding needed to make 64 bytes */
	count = 64 - 1 - count;

	/* Pad out to 56 mod 64 */
	if (count < 8) {
		/* Two lots of padding:  Pad the first block to 64 bytes */
		memset(p, 0, count);
		byteReverse(ctx->in, 16);
		MD5Transform(ctx->buf, (uint32 *) ctx->in);

		/* Now fill the next block with 56 bytes */
		memset(ctx->in, 0, 56);
	} else {
		/* Pad block to 56 bytes */
		memset(p, 0, count - 8);
	} byteReverse(ctx->in, 14);

	/* Append length in bits and transform */
	//((uint32 *) ctx->in)[14] = ctx->bits[0];
	//((uint32 *) ctx->in)[15] = ctx->bits[1];
	putu32(ctx->bits[0], ctx->in + 56);
	putu32(ctx->bits[1], ctx->in + 60);

	MD5Transform(ctx->buf, (uint32 *) ctx->in);
	byteReverse((unsigned char *) ctx->buf, 4);
	memcpy(digest, ctx->buf, 16);
	memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */
}

#ifndef ASM_MD5

/* The four core functions - F1 is optimized somewhat */

/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))

/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
	( w += f(x, y, z) + data,  w = w<<s | w>>(32-s),  w += x )

/*
 * The core of the MD5 algorithm, this alters an existing MD5 hash to
 * reflect the addition of 16 longwords of new data.  MD5Update blocks
 * the data and converts bytes into longwords for this routine.
 */
void MD5Transform(uint32 buf[4], uint32 const in[16]) {
	register uint32 a, b, c, d;

	a = buf[0];
	b = buf[1];
	c = buf[2];
	d = buf[3];

	MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
	MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
	MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
	MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
	MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
	MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
	MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
	MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
	MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
	MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
	MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
	MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
	MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
	MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
	MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
	MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);

	MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
	MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
	MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
	MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
	MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
	MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
	MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
	MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
	MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
	MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
	MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
	MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
	MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
	MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
	MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
	MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);

	MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
	MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
	MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
	MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
	MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
	MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
	MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
	MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
	MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
	MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
	MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
	MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
	MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
	MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
	MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
	MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);

	MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
	MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
	MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
	MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
	MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
	MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
	MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
	MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
	MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
	MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
	MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
	MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
	MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
	MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
	MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
	MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);

	buf[0] += a;
	buf[1] += b;
	buf[2] += c;
	buf[3] += d;
}

/*
 * get MD5 of a byte buffer
 */
int getBytesMD5(const unsigned char* src, unsigned int length, char* md5) {
	unsigned char i = 0;
	unsigned char md5Bytes[16] = { 0 };
	MD5_CTX context;
	if (src == NULL || md5 == NULL)
	{
		return -1;
	}
	MD5Init(&context);
	MD5Update(&context, src, length);
	MD5Final(md5Bytes, &context);
	for (i = 0; i < 16; i++) {
		sprintf(md5, "%02X", md5Bytes[i]);
		md5 += 2;
	}
	*md5 = '\0';
	return 0;
}

/*
 * get MD5 for a string
 */
int getStringMD5(const char* src, char* md5) {
	return getBytesMD5((unsigned char*) src, strlen((char*) src), md5);
}

/**
 * get MD5 of a file
 */
int getFileMD5(const char* path, char* md5) {
	FILE* fp = NULL;
	unsigned char buffer[MD5_FILE_BUFFER_LEN] = { 0 };
	int count = 0;
	MD5_CTX context;
	unsigned char md5Bytes[16] = { 0 };
	int i;
	if (path == NULL || md5 == NULL) {
		return -1;
	}
	fp = fopen(path, "rb");
	if (fp == NULL) {
		return -1;
	}
	MD5Init(&context);
	while ((count = fread(buffer, 1, MD5_FILE_BUFFER_LEN, fp)) > 0) {
		MD5Update(&context, buffer, count);
	}
	MD5Final(md5Bytes, &context);
	for (i = 0; i < 16; i++) {
		sprintf(md5, "%02X", md5Bytes[i]);
		md5 += 2;
	}
	*md5 = '\0';
	return 0;
}

#endif

 下面是调用函数计算MD5的代码:

main.c

 

/*
 * main.c
 *
 *  Created on: 2014-11-6
 *      Author: HZY
 */


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

#include "md5.h"

int main(int c, char** v){
	char buffer[128];
	getStringMD5("hello world", buffer);
	printf("%s\n", buffer);
	getFileMD5("hello.pdf", buffer);
	printf("%s\n", buffer);
	return 0;
}

 计算无误:



 

如果使用java的话也比较简单,java做了相应的封装:

MD5Test.java

 

package com.hu.md5;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MD5Test test = new MD5Test();
		System.out.println(test.getStringMD5("hello world"));
		System.out.println(test.getFileMD5("hello.pdf"));
	}

	/**
	 * Get MD5 of a string
	 * 
	 * @param src
	 * @return
	 */
	private String getStringMD5(String src) {
		MessageDigest messageDigest = null;
		byte[] srcBytes = src.getBytes();
		try {
			messageDigest = MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		messageDigest.update(srcBytes, 0, srcBytes.length);
		BigInteger bigInt = new BigInteger(1, messageDigest.digest());
		return bigInt.toString(16);
	}

	/**
	 * get MD5 of a file
	 * 
	 * @param file
	 * @return
	 */
	private String getFileMD5(File file) { // 获取文件的MD5值
		MessageDigest messageDigest = null;
		FileInputStream fileInStream = null;
		byte buffer[] = new byte[1024];
		int length = -1;
		try {
			messageDigest = MessageDigest.getInstance("MD5");
			fileInStream = new FileInputStream(file);
			while ((length = fileInStream.read(buffer, 0, 1024)) != -1) {
				messageDigest.update(buffer, 0, length);
			}
			fileInStream.close();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
		BigInteger bigInt = new BigInteger(1, messageDigest.digest());
		return bigInt.toString(16);
	}

	/**
	 * get MD5 of a file with file path
	 * 
	 * @param path
	 * @return
	 */
	private String getFileMD5(String path) {
		return getFileMD5(new File(path));
	}

}

 附件有相应的代码。

  • 大小: 24.9 KB
分享到:
评论

相关推荐

    5_基于MD5的文件完整性检测程序_完整性_md5算法_

    总的来说,MD5算法在文件完整性检测方面扮演了重要角色,而这个基于MD5的检测程序则提供了一个方便的工具,帮助用户快速验证文件的完整性。不过,由于MD5的安全性问题,对于涉及敏感数据的情况,建议使用更强大的...

    MD5算法BCB模块

    MD5的主要用途是验证数据的完整性,常用于文件校验、密码存储和网络传输数据的验证。 在C++Builder环境下,开发MD5功能的程序通常需要包含特定的库或自定义的类模块。在这个"MD5算法BCB模块"中,提供了一个可以在XE...

    MD5算法,求文件的MD5值

    在软件开发中,正确地实现和使用MD5可以帮助确保文件在传输或存储过程中的完整性,但需要注意的是,MD5算法已经不再被认为安全用于密码存储,因为它存在碰撞攻击的可能性。对于更安全的用途,可以考虑使用SHA-256或...

    Hash-MD5算法(C语言实现,附带Hash验证工具)

    此外,附带的7个Hash验证工具可能是为了方便用户检验MD5值的正确性,它们可能有命令行接口,接受输入的MD5摘要和文件路径,然后比较计算出的MD5值是否一致。 在使用MD5算法时,需要注意其安全性问题。由于MD5碰撞...

    验证文件完整的MD5验证器

    MD5(Message-Digest Algorithm 5)是一种广泛用于数据完整性校验和安全散列的算法。它由Ronald Rivest在1991年设计,主要用于确保数据在传输...因此,了解和使用MD5验证器对于保障数据安全和文件完整性具有重要意义。

    md5 哈希算法 数据完整性验证工具

    MD5由美国密码学家Ronald Rivest于1991年设计,尽管它在安全领域已经不再被视为安全,因为存在碰撞攻击的可能性,但在验证数据完整性方面仍有一定的应用。 SHA(Secure Hash Algorithm)家族包括SHA-1和SHA-2(包括...

    C语言MD5算法STM32单片机亲测可用

    在C语言中实现MD5算法,可以用于数据完整性校验、密码存储等方面。 在STM32单片机上应用MD5算法,首先需要理解STM32的基本架构。STM32是基于ARM Cortex-M系列内核的微控制器,具有高性能、低功耗的特点。在STM32上...

    MD5算法研究.pdf

    1. **文件校验**:通过计算文件的MD5摘要,可以验证文件在传输或存储过程中的完整性。如果文件的MD5值与原始值不同,那么可以判断文件可能被篡改或损坏。 2. **密码存储**:在很多系统中,用户的密码并不直接存储,...

    MD5算法代码

    MD5的主要应用是验证数据的完整性和一致性,特别是在文件传输、软件下载和密码存储等领域。 MD5的工作原理基于分块处理和一系列复杂的数学运算,包括位操作、加法、异或和旋转等。它将输入数据分成512位的块,并对...

    md5算法摘要实例

    `testMd5`可能是用以测试MD5实现的示例程序,它可能包含一段代码,读取一个文件内容,然后计算并打印出该文件的MD5摘要,以此验证算法的正确性。 使用MD5时,需要注意的是,由于MD5算法的安全性问题,它已经不再...

    利用JAVASCRIPT HMAC-MD5算法增强用户的密码安全

    而HMAC(Hash-based Message Authentication Code)是基于密钥的哈希函数,用于验证数据的完整性和来源的可靠性。它结合了密钥和MD5算法,为密码提供额外的安全层。 HMAC-MD5的工作原理是通过将密钥和消息一起输入...

    MD5算法源码;加密算法

    MD5的主要应用是验证数据的完整性和一致性,例如在软件下载、密码存储和数字签名等领域。 在C++中实现MD5算法,你需要理解以下几个关键概念: 1. **MD5的基本结构**:MD5算法由四个不同的处理函数(F, G, H, I)和...

    MD5加密算法

    MD5的主要应用在于数据完整性校验、文件校验和以及密码存储。 在网络安全领域,MD5被广泛用于数字签名。数字签名是一种用于验证信息完整性和发送者身份的技术。通过MD5,发送者可以对信息生成一个唯一的数字指纹,...

    MD5算法源码 下载

    MD5的主要应用是验证数据完整性,比如在下载文件后计算其MD5值并与提供者给出的MD5值比较,确保文件在传输过程中没有被篡改。尽管MD5的安全性在近年来已被削弱,不再适用于密码存储或高度安全的认证场景,但在一些非...

    md5 算法

    使用这些函数,开发者可以很容易地将MD5整合到他们的C程序中,以检查文件的完整性或处理密码。然而,需要注意的是,MD5由于其安全性问题(易遭碰撞攻击),已经不再适合用于密码存储和安全认证。尽管如此,MD5仍然是...

    三种语言md5加密算法

    6. **使用说明**:`md5使用说明.txt`文件应该包含了如何在不同语言环境下使用这些MD5加密算法的详细步骤和示例。通常会包括代码片段、依赖库的安装指南、如何调用函数以及如何解释和比较MD5摘要等内容。 在实际项目...

    MD5自动校验算法程序源代码

    源代码中可能还会包含示例用法,展示如何使用这些函数来计算文件的MD5值,并与预期值进行比较,从而完成文件的完整性验证。学习和理解这些源代码可以帮助开发者更好地理解和应用MD5算法,也可以为开发自己的校验工具...

    verilog MD5算法

    本篇文档介绍的是一个基于Verilog HDL语言实现的MD5算法模块,该模块可以直接应用于嵌入式系统中,并且提供了完整的仿真验证结果,确保了其实现的正确性。接下来将详细介绍此模块的设计原理、内部结构以及如何在实际...

Global site tag (gtag.js) - Google Analytics