Click here to Skip to main content
Licence CPOL
First Posted 19 Jun 2002
Views 345,910
Downloads 8,057
Bookmarked 138 times

CSHA1 - A C++ Class Implementation of the SHA-1 Hash Algorithm

By | 10 Nov 2011 | Article
CSHA1 - A C++ class implementation of the SHA-1 hash algorithm

Contents

Description of the Secure Hash Algorithm SHA-1

The Secure Hash Algorithm SHA-1 is a cryptographically secure one-way hash algorithm. It was designed by the NIST (National Institute of Standards and Technology), along with the NSA (National Security Agency). SHA-1 is based on the Message Digest MD4 algorithm design principles by Ronald L. Rivest of MIT.

Well, I think I don't have to explain what you can do with cryptographic hash algorithms. For an example what you can do with such algorithms, see this CodeProject article (CMD5 class).

For more information about SHA-1, see references [1] and [2].

CSHA1 Class Description

The CSHA1 class is an easy-to-use class for the SHA-1 hash algorithm.

If you want to test if your implementation of the class is working, try the test vectors in the 'TestVectors' directory in the demo zip file. You can find the correct hash values in the header file of the CSHA1 class.

Class members of the CSHA1 class:

  • void Reset();

    This member function resets the class. You have to call this method when using CSHA1 more than one time. This method is called automatically in the constructor and the destructor of the class so if you only hash one single data stream you don't need to call Reset() manually.

  • void Update(const UINT_8* pbData, UINT_32 uLen);

    Use this method to hash in a data stream. Data in const UINT_8* pbData, length of stream has to be submitted in UINT_32 uLen. Length in bytes.

  • bool HashFile(const TCHAR* tszFileName);

    This method hashes file contents into the current state. If hashing was successful, the method returns true, otherwise false. If you use this member function, you don't need to make any call to the Update(...) method. After HashFile(...) you should call the Final() method immediately. You have to call Final() before getting the message digest of the file using the methods ReportHash(...) and GetHash(...).

  • void Final();

    When you have hashed in all data to hash, call this method. This will compute the final SHA-1 message digest and it is therefore needed to call this method before ReportHash(...) and GetHash(...).

  • bool ReportHash(TCHAR* tszReport, REPORT_TYPE rtReportType = REPORT_HEX) const;

    After calling the Final method, you can get the message digest using this method. The result is stored as string in tszReport. Valid format types for uReportType are REPORT_HEX, REPORT_DIGIT and REPORT_HEX_SHORT. If you use REPORT_HEX, the returned string looks like 5F A9 FB 34..., using REPORT_DIGIT this method returns the message digest in the form 129 67 5 98... . REPORT_HEX_SHORT is the same as REPORT_HEX, just without separating spaces.

  • bool GetHash(UINT_8* pbDest20) const;

    If you don't want to get the hash in a pre-formatted string using ReportHash, you can use this method. This method copies the final message digest (call Final before!) to pbDest20. pbDest must be able to hold at least 20 bytes (SHA-1 produces a 160-bit / 20-byte hash).

Hashing Binary Data and Strings

CSHA1 sha1;
sha1.Update(string0, strlen(string0));
sha1.Update(string1, strlen(string1));
sha1.Update(binary2, uSizeOfBufferBinary2);
sha1.Update(binary3, uSizeOfBufferBinary3);
sha1.Final();

sha1.ReportHash(szReport, CSHA1::REPORT_HEX_SHORT);
// or
sha1.GetHash(binaryArray);

I will comment each line of the example above now.

First, declare an instance of the CSHA1 class:

CSHA1 sha1;

Now hash in the data like this:

sha1.Update((unsigned char *)szString, strlen(szString));

You can call this method as often as you wish.

When you hashed in all data, call the Final() member function:

sha1.Final();

If you want to get the final message digest as a pre-formatted string, use this:

sha1.ReportHash(szReport, CSHA1::REPORT_HEX_SHORT);

If you want to get the final message digest in "raw form":

sha1.GetHash(binaryArray); // Get the raw message digest bytes

Hashing Files

Hashing files is the same process as hashing strings and binary data but instead of using the Update method, you use the HashFile member function of the class.

For more comments, see the string/binary data hashing example above.

CSHA1 sha1;
sha1.HashFile("TheFile.cpp"); // Hash in the contents of the file
                              // 'TheFile.cpp'
sha1.Final();

sha1.ReportHash(szReport, CSHA1::REPORT_HEX); // Get final hash as
                                              // pre-formatted string
// or
sha1.GetHash(binaryArray); // Get the raw message digest bytes to a
                           // temporary buffer

References

[1] RFC 3174: US Secure Hash Algorithm 1 (SHA1)
[2] Bruce Schneier, Applied Cryptography, pages 442-445

Version History

  • Version 1.9 - 2011-11-10
    • Added Unicode test vectors
    • Improved support for hashing files using the HashFile method that are larger than 4 GB
    • Improved file hashing performance (by using a larger buffer)
    • Disabled unnecessary compiler warnings
    • Internal variables are now private
  • Version 1.8 - 2009-03-16
    • Converted project files to Visual Studio 2008 format
    • Added Unicode support for HashFile utility method
    • Added support for hashing files using the HashFile method that are larger than 2 GB.
    • HashFile now returns an error code instead of copying an error message into the output buffer
    • GetHash now returns an error code and validates the input parameter
    • Added ReportHashStl STL utility method
    • Added REPORT_HEX_SHORT reporting mode
    • Improved Linux compatibility of test program
  • Version 1.7 - 2006-12-21
    • Fixed buffer underrun warning that appeared when compiling with Borland C Builder (thanks to Rex Bloom and Tim Gallagher for the patch)
    • Breaking change: ReportHash writes the final hash to the start of the buffer, i.e. it's not appending it to the string anymore
    • Made some function parameters const
    • Added Visual Studio 2005 project files to demo project
  • Version 1.6 - 2005-02-07
    • You can set the endianness in your files, no need to modify the header file of the CSHA1 class anymore
    • Aligned data support
    • Made support/compilation of the utility functions (ReportHash and HashFile) optional (useful when bytes count, for example in embedded environments)
    • Thanks to Howard Kapustein for patches
  • Version 1.5 - 2005-01-01
    • 64-bit compiler compatibility added
    • Made variable wiping optional (define SHA1_WIPE_VARIABLES)
    • Removed unnecessary variable initializations
    • ROL32 improvement for the Microsoft compiler (using _rotl)
  • Version 1.4 - 2004-07-22
    • CSHA1 now compiles fine with GCC 3.3 under MacOS X (thanks to Larry Hastings)
  • Version 1.3 - 2003-08-17
    • Fixed a small memory bug and made a buffer array a class member to ensure correct working when using multiple CSHA1 class instances at one time
  • Version 1.2 - 2002-11-16
    • Borlands C++ compiler seems to have problems with string addition using sprintf. Fixed the bug which caused the digest report function not to work properly. CSHA1 is now Borland compatible.
  • Version 1.1 - 2002-10-11
    • Removed two unnecessary header file includes and changed BOOL to bool. Fixed some minor bugs in the web page contents
  • Version 1.0 - 2002-06-20
    • First official release

That's it! Happy hashing!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Dominik Reichl

Software Developer

Germany Germany

Member

Dominik started programming in Omikron Basic, a programming language for the good old Atari ST. After this, there was some short period of QBasic programming on the PC, but soon he began learning C++, which is his favorite language up to now.
 
Today, his programming experience includes C / C++ / [Visual] C++ [MFC], C#/.NET, Java, JavaScript, PHP and HTML and the basics of pure assembler.
 
He is interested in almost everything that has to do with computing, his special interests are security and data compression.
 
You can find his latest freeware, open-source projects and all articles on his homepage: http://www.dominik-reichl.de/

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
GeneralRe: SHA1 Hash does not give same hash as NET SHA1 PinmemberKilty8:13 30 Nov '06  
GeneralRe: SHA1 Hash does not give same hash as NET SHA1 PinmemberVladaTzar0:57 13 Jun '10  
GeneralRe: SHA1 Hash does not give same hash as NET SHA1 PinmemberDominik Reichl1:06 13 Jun '10  
GeneralRe: SHA1 Hash does not give same hash as NET SHA1 PinmemberVladaTzar1:14 13 Jun '10  
GeneralRe: SHA1 Hash does not give same hash as NET SHA1 PinmemberVladaTzar1:30 13 Jun '10  
QuestionLimitation: Adding iostream Gives Compiler Errors Pinmemberalam008:53 20 May '06  
AnswerRe: Limitation: Adding iostream Gives Compiler Errors PinmemberKapali Viswanathan7:05 6 Jun '06  
Hi
 
I had a similar problem (relating to the linker and not to the compiler -- I was getting a "undefined reference to" message from the linker).
 
RESOLUTION: ensure that SHA1.h is the first include before every other #include statement in your source code (client application). This worked for me while using latest version of g++ on Linux.
 
POSSIBLE CAUSE: I guess that there should be two independent causes to result in this problem. Let your code that depends on SHA1.cpp be called the client application.
1. the iostream library, or some other library that it uses, defines UINT_32 and UINT_8, if they are not already defined, to be unsigned long while SHA1.cpp defines it to unsigned int on Linux
2. g++ compiles SHA1.cpp first and independently of the client application both depending on SHA1.h.
 
So the object file from SHA1.cpp has definition for UINT_32 as unsigned int while the object file for the client application has definition for UINT_32 as unsigned long. Since C++ is a more strongly typed language that C, it thinks that foo(unsigned int) and foo(unsinged long) are two different functions -- which is essential for function overloading purposes. later program can potentially define it to be unsigned long. Clearly the signatures of all functions would potentially become incompatible.
 
COMMENT: The resolution is not a nice one but works for me. A better resolution would be to rework the following part of SHA1.h so that it resolves things properly on non-microsoft platforms as well.
 
#ifndef UINT_32
#ifdef _MSC_VER
 
#define UINT_8 unsigned __int8
#define UINT_32 unsigned __int32
 
#else
 
#define UINT_8 unsigned char
 
#if (ULONG_MAX == 0xFFFFFFFF)
#define UINT_32 unsigned long
#else
#define UINT_32 unsigned int
#endif
 
#endif
#endif
 
Regards,
Kapali
 
Kapali Viswanthan
Generalerreur LIBCD.lib Pinmemberramzi200622:54 18 Feb '06  
Generalconst char * Pinmemberbramp4:30 10 Jan '06  
GeneralThanks for contributing this PinmemberGadgetMan663:46 21 Dec '05  
Generalthanx a lot! Pinmemberzoz2:09 27 Nov '05  
Generaladding iostream and fstream Pinmembernmullane17:20 22 Oct '05  
GeneralRe: adding iostream and fstream PinmemberMiroslav Rajcic1:57 16 Oct '06  
GeneralRe: adding iostream and fstream PinmemberMiroslav Rajcic2:08 16 Oct '06  
GeneralRe: adding iostream and fstream [modified] Pinmemberegmont6421:23 31 Oct '06  
QuestionWhy do you call Reset in the destructor? PinsussDave Lowndes10:08 8 Sep '05  
GeneralPrepend garbage value PinmemberSubrat B.21:38 10 Jul '05  
GeneralRe: Prepend garbage value PinmemberMike Walter22:04 10 Jul '05  
GeneralRe: Prepend garbage value PinmemberSubrat B.22:35 10 Jul '05  
GeneralCompiler Error Pinmemberscott_Acts8_378:32 15 Apr '05  
GeneralRe: Compiler Error Pinmemberscott_Acts8_3710:11 15 Apr '05  
GeneralSome arguments sould be const Pinmemberbrisemec12:10 4 Apr '05  
GeneralCSHA1 on Mac Pinmembernudelsnack4:41 2 Apr '05  
GeneralRe: CSHA1 on Mac Pinmembernudelsnack12:32 7 Apr '05  
GeneralSHA-1 broken recently. Pinmembergschultz5:20 17 Feb '05  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 10 Nov 2011
Article Copyright 2002 by Dominik Reichl
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid