📄 md5.h
字号:
/*
Copyright 2006 - 2008, All Rights Reserved.
MD5算法实现, 根据rfc1321.txt中的源码封装成C++类,
详细算法流程请参见rfc1321.txt
作者 - 张鲁夺(zhangluduo)
MSN - zhangluduo@msn.com
QQ群 - 34064264
为所有爱我的人和我爱的人努力!
*/
#ifndef _MD5_H
#define _MD5_H
class MD5
{
public:
MD5();
virtual ~MD5();
public:
// MD5 context.
struct MD5_CTX
{
unsigned long state[4]; // state (ABCD)
unsigned long count[2]; // number of bits, modulo 2^64 (lsb first)
unsigned char buffer[64]; // input buffer
};
private:
// this value must initialize first
unsigned char PADDING[64];
private:
/** Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
void Encode (unsigned char *output, unsigned long *input, unsigned int len);
/** Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
void Decode (unsigned long* output, unsigned char *input, unsigned int len);
/** Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
void MD5_memset (unsigned char* output, int value, unsigned int len);
// Note: Replace "for loop" with standard memcpy if possible.
void MD5_memcpy (unsigned char* output, unsigned char* input, unsigned int len);
public:
/** step 1
MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (struct MD5_CTX *context);
/** step 2
MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (struct MD5_CTX *context /* context */,
unsigned char *input /* input block */,
unsigned int inputLen /* length of input block */);
/** step 3
MD5 basic transformation. Transforms state based on block.
*/
private : void MD5Transform (unsigned long state[4], unsigned char block[64]);
public:
/** step 4
MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (unsigned char digest[16]/* message digest */, MD5_CTX *context /* context */);
};
#endif
/*
// ----------------
// demo
// ----------------
// input data
unsigned char *pData = (unsigned char *)"0123456789";
unsigned long DataLen = strlen((const char *)pData);
MD5 md5; // md5 object
MD5::MD5_CTX context; // md5 context
unsigned char digest[16]; // result
md5.MD5Init (&context);
md5.MD5Update (&context, pData, DataLen);
md5.MD5Final (digest, &context);
// show result
// #pragma warning(disable : 4786)
// #include <string>
// using namespace std;
string strResulr = "";
for(int i = 0 ; i < 16; i++)
{
char buf[3] = {0};
sprintf(buf, "%.2X", digest[i]);
strResulr += buf;
}
AfxMessageBox(strResulr.c_str());
*/
// rfc1321.txt
//
// Network Working Group R. Rivest
// Request for Comments: 1321 MIT Laboratory for Computer Science
// and RSA Data Security, Inc.
// April 1992
//
//
// The MD5 Message-Digest Algorithm
//
// Status of this Memo
//
// This memo provides information for the Internet community. It does
// not specify an Internet standard. Distribution of this memo is
// unlimited.
//
// Acknowlegements
//
// We would like to thank Don Coppersmith, Burt Kaliski, Ralph Merkle,
// David Chaum, and Noam Nisan for numerous helpful comments and
// suggestions.
//
// Table of Contents
//
// 1. Executive Summary 1
// 2. Terminology and Notation 2
// 3. MD5 Algorithm Description 3
// 4. Summary 6
// 5. Differences Between MD4 and MD5 6
// References 7
// APPENDIX A - Reference Implementation 7
// Security Considerations 21
// Author's Address 21
//
// 1. Executive Summary
//
// This document describes the MD5 message-digest algorithm. The
// algorithm takes as input a message of arbitrary length and produces
// as output a 128-bit "fingerprint" or "message digest" of the input.
// It is conjectured that it is computationally infeasible to produce
// two messages having the same message digest, or to produce any
// message having a given prespecified target message digest. The MD5
// algorithm is intended for digital signature applications, where a
// large file must be "compressed" in a secure manner before being
// encrypted with a private (secret) key under a public-key cryptosystem
// such as RSA.
//
// Rivest [Page 1]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// The MD5 algorithm is designed to be quite fast on 32-bit machines. In
// addition, the MD5 algorithm does not require any large substitution
// tables; the algorithm can be coded quite compactly.
//
// The MD5 algorithm is an extension of the MD4 message-digest algorithm
// 1,2]. MD5 is slightly slower than MD4, but is more "conservative" in
// design. MD5 was designed because it was felt that MD4 was perhaps
// being adopted for use more quickly than justified by the existing
// critical review; because MD4 was designed to be exceptionally fast,
// it is "at the edge" in terms of risking successful cryptanalytic
// attack. MD5 backs off a bit, giving up a little in speed for a much
// greater likelihood of ultimate security. It incorporates some
// suggestions made by various reviewers, and contains additional
// optimizations. The MD5 algorithm is being placed in the public domain
// for review and possible adoption as a standard.
//
// For OSI-based applications, MD5's object identifier is
//
// md5 OBJECT IDENTIFIER ::=
// iso(1) member-body(2) US(840) rsadsi(113549) digestAlgorithm(2) 5}
//
// In the X.509 type AlgorithmIdentifier [3], the parameters for MD5
// should have type NULL.
//
// 2. Terminology and Notation
//
// In this document a "word" is a 32-bit quantity and a "byte" is an
// eight-bit quantity. A sequence of bits can be interpreted in a
// natural manner as a sequence of bytes, where each consecutive group
// of eight bits is interpreted as a byte with the high-order (most
// significant) bit of each byte listed first. Similarly, a sequence of
// bytes can be interpreted as a sequence of 32-bit words, where each
// consecutive group of four bytes is interpreted as a word with the
// low-order (least significant) byte given first.
//
// Let x_i denote "x sub i". If the subscript is an expression, we
// surround it in braces, as in x_{i+1}. Similarly, we use ^ for
// superscripts (exponentiation), so that x^i denotes x to the i-th
// power.
//
// Let the symbol "+" denote addition of words (i.e., modulo-2^32
// addition). Let X <<< s denote the 32-bit value obtained by circularly
// shifting (rotating) X left by s bit positions. Let not(X) denote the
// bit-wise complement of X, and let X v Y denote the bit-wise OR of X
// and Y. Let X xor Y denote the bit-wise XOR of X and Y, and let XY
// denote the bit-wise AND of X and Y.
//
// Rivest [Page 2]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// 3. MD5 Algorithm Description
//
// We begin by supposing that we have a b-bit message as input, and that
// we wish to find its message digest. Here b is an arbitrary
// nonnegative integer; b may be zero, it need not be a multiple of
// eight, and it may be arbitrarily large. We imagine the bits of the
// message written down as follows:
//
// m_0 m_1 ... m_{b-1}
//
// The following five steps are performed to compute the message digest
// of the message.
//
// 3.1 Step 1. Append Padding Bits
//
// The message is "padded" (extended) so that its length (in bits) is
// congruent to 448, modulo 512. That is, the message is extended so
// that it is just 64 bits shy of being a multiple of 512 bits long.
// Padding is always performed, even if the length of the message is
// already congruent to 448, modulo 512.
//
// Padding is performed as follows: a single "1" bit is appended to the
// message, and then "0" bits are appended so that the length in bits of
// the padded message becomes congruent to 448, modulo 512. In all, at
// least one bit and at most 512 bits are appended.
//
// 3.2 Step 2. Append Length
//
// A 64-bit representation of b (the length of the message before the
// padding bits were added) is appended to the result of the previous
// step. In the unlikely event that b is greater than 2^64, then only
// the low-order 64 bits of b are used. (These bits are appended as two
// 32-bit words and appended low-order word first in accordance with the
// previous conventions.)
//
// At this point the resulting message (after padding with bits and with
// b) has a length that is an exact multiple of 512 bits. Equivalently,
// this message has a length that is an exact multiple of 16 (32-bit)
// words. Let M[0 ... N-1] denote the words of the resulting message,
// where N is a multiple of 16.
//
// 3.3 Step 3. Initialize MD Buffer
//
// A four-word buffer (A,B,C,D) is used to compute the message digest.
// Here each of A, B, C, D is a 32-bit register. These registers are
// initialized to the following values in hexadecimal, low-order bytes
// first):
//
// Rivest [Page 3]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// word A: 01 23 45 67
// word B: 89 ab cd ef
// word C: fe dc ba 98
// word D: 76 54 32 10
//
// 3.4 Step 4. Process Message in 16-Word Blocks
//
// We first define four auxiliary functions that each take as input
// three 32-bit words and produce as output one 32-bit word.
//
// F(X,Y,Z) = XY v not(X) Z
// G(X,Y,Z) = XZ v Y not(Z)
// H(X,Y,Z) = X xor Y xor Z
// I(X,Y,Z) = Y xor (X v not(Z))
//
// In each bit position F acts as a conditional: if X then Y else Z.
// The function F could have been defined using + instead of v since XY
// and not(X)Z will never have 1's in the same bit position.) It is
// interesting to note that if the bits of X, Y, and Z are independent
// and unbiased, the each bit of F(X,Y,Z) will be independent and
// unbiased.
//
// The functions G, H, and I are similar to the function F, in that they
// act in "bitwise parallel" to produce their output from the bits of X,
// Y, and Z, in such a manner that if the corresponding bits of X, Y,
// and Z are independent and unbiased, then each bit of G(X,Y,Z),
// H(X,Y,Z), and I(X,Y,Z) will be independent and unbiased. Note that
// the function H is the bit-wise "xor" or "parity" function of its
// inputs.
//
// This step uses a 64-element table T[1 ... 64] constructed from the
// sine function. Let T[i] denote the i-th element of the table, which
// is equal to the integer part of 4294967296 times abs(sin(i)), where i
// is in radians. The elements of the table are given in the appendix.
//
// Do the following:
//
// /* Process each 16-word block. */
// For i = 0 to N/16-1 do
//
// /* Copy block i into X. */
// For j = 0 to 15 do
// Set X[j] to M[i*16+j].
// end /* of loop on j */
//
// /* Save A as AA, B as BB, C as CC, and D as DD. */
// AA = A
// BB = B
//
// Rivest [Page 4]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// CC = C
// DD = D
//
// /* Round 1. */
// /* Let [abcd k s i] denote the operation
// a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */
// /* Do the following 16 operations. */
// [ABCD 0 7 1] [DABC 1 12 2] [CDAB 2 17 3] [BCDA 3 22 4]
// [ABCD 4 7 5] [DABC 5 12 6] [CDAB 6 17 7] [BCDA 7 22 8]
// [ABCD 8 7 9] [DABC 9 12 10] [CDAB 10 17 11] [BCDA 11 22 12]
// [ABCD 12 7 13] [DABC 13 12 14] [CDAB 14 17 15] [BCDA 15 22 16]
//
// /* Round 2. */
// /* Let [abcd k s i] denote the operation
// a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */
// /* Do the following 16 operations. */
// [ABCD 1 5 17] [DABC 6 9 18] [CDAB 11 14 19] [BCDA 0 20 20]
// [ABCD 5 5 21] [DABC 10 9 22] [CDAB 15 14 23] [BCDA 4 20 24]
// [ABCD 9 5 25] [DABC 14 9 26] [CDAB 3 14 27] [BCDA 8 20 28]
// [ABCD 13 5 29] [DABC 2 9 30] [CDAB 7 14 31] [BCDA 12 20 32]
//
// /* Round 3. */
// /* Let [abcd k s t] denote the operation
// a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */
// /* Do the following 16 operations. */
// [ABCD 5 4 33] [DABC 8 11 34] [CDAB 11 16 35] [BCDA 14 23 36]
// [ABCD 1 4 37] [DABC 4 11 38] [CDAB 7 16 39] [BCDA 10 23 40]
// [ABCD 13 4 41] [DABC 0 11 42] [CDAB 3 16 43] [BCDA 6 23 44]
// [ABCD 9 4 45] [DABC 12 11 46] [CDAB 15 16 47] [BCDA 2 23 48]
//
// /* Round 4. */
// /* Let [abcd k s t] denote the operation
// a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */
// /* Do the following 16 operations. */
// [ABCD 0 6 49] [DABC 7 10 50] [CDAB 14 15 51] [BCDA 5 21 52]
// [ABCD 12 6 53] [DABC 3 10 54] [CDAB 10 15 55] [BCDA 1 21 56]
// [ABCD 8 6 57] [DABC 15 10 58] [CDAB 6 15 59] [BCDA 13 21 60]
// [ABCD 4 6 61] [DABC 11 10 62] [CDAB 2 15 63] [BCDA 9 21 64]
//
// /* Then perform the following additions. (That is increment each
// of the four registers by the value it had before this block
// was started.) */
// A = A + AA
// B = B + BB
// C = C + CC
// D = D + DD
//
// end /* of loop on i */
//
// Rivest [Page 5]
//
// RFC 1321 MD5 Message-Digest Algorithm April 1992
//
//
// 3.5 Step 5. Output
//
// The message digest produced as output is A, B, C, D. That is, we
// begin with the low-order byte of A, and end with the high-order byte
// of D.
//
// This completes the description of MD5. A reference implementation in
// C is given in the appendix.
//
// 4. Summary
//
// The MD5 message-digest algorithm is simple to implement, and provides
// a "fingerprint" or message digest of a message of arbitrary length.
// It is conjectured that the difficulty of coming up with two messages
// having the same message digest is on the order of 2^64 operations,
// and that the difficulty of coming up with any message having a given
// message digest is on the order of 2^128 operations. The MD5 algorithm
// has been carefully scrutinized for weaknesses. It is, however, a
// relatively new algorithm and further security analysis is of course
// justified, as is the case with any new proposal of this sort.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -