md5class.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // md5class.h: interface for the CMD5 class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #if !defined(AFX_MD51_H__2A1EA377_D065_11D4_A8C8_0050DAC6D85C__INCLUDED_)
  5. #define AFX_MD51_H__2A1EA377_D065_11D4_A8C8_0050DAC6D85C__INCLUDED_
  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000
  9. /***************************************************************************
  10. This class is a utility wrapper for 'C' code contained in internet RFC 1321,
  11. "The MD5 Message-Digest Algorithm".
  12. It calculates a cryptological hash value, called a "digest" from a character
  13. string. For every unique character string the MD5 hash is guaranteed to be
  14. unique. The MD5 hash has the property that given the digest, it's
  15. thought to be impossible to get back to the plain text string with existing
  16. technology. In this implementation the digest is always a 32 digit hex number,
  17. regardless of the length of the input plaintext.
  18. This class is helpful for programs which store passwords. Rather than storing
  19. the password directly, the programmer should store the MD5 digest of the password.
  20. Then when the user enters a password, compute the MD5 digest of the input password.
  21. If it is identical to the stored digest, then the user
  22. has entered the correct password. It doesn't matter if an evil person sees the
  23. digest, since he or she can't get from the digest to the password. At least not
  24. unless the user enters a word out of the dictionary, since the evil person could
  25. hash the whole dictionary. One way to defeat a dictionary attack is to append
  26. a non-text character onto the password, so that even if the user enters a dumb
  27. password like "password", you just append some non alpha character to the entered
  28. password, i.e. password = "password" + "$". By always appending a nonalpha
  29. character, your stored digest isn't in the attacker's dictionary. You can
  30. then safely post the digest of the password on a highway billboard.
  31. Example pseudocode:
  32. {
  33. std::string storedPasswordDigest = GetPasswordDigestFromStorage();
  34. std::string passwordEnteredbyUser;
  35. cout << "Enter password:" ;
  36. cin >> passwordEnteredbyUser;
  37. 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.
  38. if(md5.getMD5Digest != storedPasswordDigest)
  39. {
  40. //user has entered an invalid password
  41. cout << "Incorrect password!";
  42. exit(1);
  43. }
  44. //if we get here, then the user entered a valid password
  45. }
  46. **************************************************************************
  47. Use this code as you see fit. It is provided "as is"
  48. without express or implied warranty of any kind.
  49. Jim Howard, jnhtx@jump.net
  50. ***************************************************************************/
  51. class CMD5
  52. {
  53. public:
  54. CMD5(); //default ctor
  55. CMD5(const char* plainText); //set plaintext in ctor
  56. void setPlainText(const char* plainText); //set plaintext with a mutator, it's ok to
  57. //to call this multiple times, the digest is recalculated after each call.
  58. const char* getMD5Digest(); //access message digest (aka hash), return 0 if plaintext has not been set
  59. virtual ~CMD5();
  60. private:
  61. bool calcDigest(); //this function computes the digest by calling the RFC 1321 'C' code
  62. bool m_digestValid; //false until the plaintext has been set and digest computed
  63. unsigned char m_digest[16]; //the numerical value of the digest
  64. char m_digestString[33]; //Null terminated string value of the digest expressed in hex digits
  65. char* m_plainText; //a pointer to the plain text. If casting away the const-ness
  66. //worries you, you could either make a local copy of the plain
  67. //text string instead of just pointing at the user's string or
  68. //modify the RFC 1321 code to take 'const' plaintext.
  69. };
  70. #endif // !defined(AFX_MD51_H__2A1EA377_D065_11D4_A8C8_0050DAC6D85C__INCLUDED_)