00001 // md5class.h: interface for the CMD5 class. 00002 // 00004 00005 #if !defined(AFX_MD51_H__2A1EA377_D065_11D4_A8C8_0050DAC6D85C__INCLUDED_) 00006 #define AFX_MD51_H__2A1EA377_D065_11D4_A8C8_0050DAC6D85C__INCLUDED_ 00007 00008 #if _MSC_VER > 1000 00009 #pragma once 00010 #endif // _MSC_VER > 1000 00011 00012 00013 /*************************************************************************** 00014 00015 This class is a utility wrapper for 'C' code contained in internet RFC 1321, 00016 "The MD5 Message-Digest Algorithm". 00017 00018 It calculates a cryptological hash value, called a "digest" from a character 00019 string. For every unique character string the MD5 hash is guaranteed to be 00020 unique. The MD5 hash has the property that given the digest, it's 00021 thought to be impossible to get back to the plain text string with existing 00022 technology. In this implementation the digest is always a 32 digit hex number, 00023 regardless of the length of the input plaintext. 00024 00025 This class is helpful for programs which store passwords. Rather than storing 00026 the password directly, the programmer should store the MD5 digest of the password. 00027 Then when the user enters a password, compute the MD5 digest of the input password. 00028 If it is identical to the stored digest, then the user 00029 has entered the correct password. It doesn't matter if an evil person sees the 00030 digest, since he or she can't get from the digest to the password. At least not 00031 unless the user enters a word out of the dictionary, since the evil person could 00032 hash the whole dictionary. One way to defeat a dictionary attack is to append 00033 a non-text character onto the password, so that even if the user enters a dumb 00034 password like "password", you just append some non alpha character to the entered 00035 password, i.e. password = "password" + "$". By always appending a nonalpha 00036 character, your stored digest isn't in the attacker's dictionary. You can 00037 then safely post the digest of the password on a highway billboard. 00038 00039 Example pseudocode: 00040 { 00041 std::string storedPasswordDigest = GetPasswordDigestFromStorage(); 00042 std::string passwordEnteredbyUser; 00043 cout << "Enter password:" ; 00044 cin >> passwordEnteredbyUser; 00045 00046 CMD5 md5(passwordEnteredbyUser.c_str()); //note c_str() returns a pointer to the std::string's character buffer, just like CString's "GetBuffer" member function. 00047 00048 if(md5.getMD5Digest != storedPasswordDigest) 00049 { 00050 //user has entered an invalid password 00051 cout << "Incorrect password!"; 00052 exit(1); 00053 } 00054 00055 //if we get here, then the user entered a valid password 00056 } 00057 ************************************************************************** 00058 Use this code as you see fit. It is provided "as is" 00059 without express or implied warranty of any kind. 00060 00061 Jim Howard, jnhtx@jump.net 00062 ***************************************************************************/ 00063 00064 class CMD5 00065 { 00066 public: 00067 CMD5(); //default ctor 00068 CMD5(const char* plainText); //set plaintext in ctor 00069 void setPlainText(const char* plainText); //set plaintext with a mutator, it's ok to 00070 //to call this multiple times, the digest is recalculated after each call. 00071 const char* getMD5Digest(); //access message digest (aka hash), return 0 if plaintext has not been set 00072 00073 virtual ~CMD5(); 00074 private: 00075 bool calcDigest(); //this function computes the digest by calling the RFC 1321 'C' code 00076 00077 bool m_digestValid; //false until the plaintext has been set and digest computed 00078 unsigned char m_digest[16]; //the numerical value of the digest 00079 char m_digestString[33]; //Null terminated string value of the digest expressed in hex digits 00080 char* m_plainText; //a pointer to the plain text. If casting away the const-ness 00081 //worries you, you could either make a local copy of the plain 00082 //text string instead of just pointing at the user's string or 00083 //modify the RFC 1321 code to take 'const' plaintext. 00084 00085 }; 00086 00087 #endif // !defined(AFX_MD51_H__2A1EA377_D065_11D4_A8C8_0050DAC6D85C__INCLUDED_)