Main Page | Class List | File List | Class Members

md5.h

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_)

Generated on Tue Oct 25 23:04:38 2005 for fortress by  doxygen 1.4.2