Leave Comments, Critiques, and Suggestions Here?
Table of Contents
Tango Cryptography and Encoding
The Cryptography and Encoding portion of the Tango library defines interfaces for creating hashes of an arbitrary buffer. Hashes can be used for a variety of purposes. Some are used in serial communications to make sure a buffer hasn’t been corrupted during transmission. Some are used as digital signatures – proof that you are who you say you are. Similarly, some are used as part of an authentication header, such as those defined by IPSEC. In any case, the Tango library provides you with easy to use interfaces to leverage this capability in your own application.
The Tango library encapsulates the basic behaviors of these hash functions with the base class Digest. Once this simple interface is understood you will be able to make use of the following hash algorithms:
- General
- CRC 32
- Secure
- MD2, MD4, MD5
- SHA0, SHA1, SHA256, SHA512
- Tiger
How it works
At the highest level a cipher is capable of generating a hash using the .update(void[]) method. The cipher encapsulate the algorithms used to generate a hash. The Digest base class of all chipher classes let you provide the cipher with new data and give access to the results of the hash operation.
Do it all at once
To create a hash of an entire buffer you use the update method of the Digest class.
Digest digest = new Crc32(); // process the data digest.update("The quick brown fox jumps over the lazy dog");
Do it as part of a stream
To create a hash of an ongoing stream you use the update method of Digest.
// create an MD5 cipher Digest digest = new Md5(); // process some data digest.update("The quick brown fox"); // process some more data digest.update(" jumps over the lazy dog"); // conclude cipher and produce digest ubyte[] hash = digest.binaryDigest()
Getting the results
Once you’ve generated your hash you can get the results by using the Digest classes. Digest supports the following two methods:
- hexDigest() – use this to generate a human readable hex representation of the hash
- binaryDigest() – use this to generate a binary representation of the hash.
Exceptions
The Tango library defines Exceptions to handle error conditions as required. Digest should not throw any Exception
Putting it all together
The following simple program illustrates what we’ve learned so far. This program will accept a string from the command line and create the requested hash of that string.
module ciphertest; import tango.io.Console; import tango.io.digest.Crc32; import tango.io.digest.Md2; import tango.io.digest.Md4; import tango.io.digest.Md5; import tango.io.digest.Sha0; import tango.io.digest.Sha1; import tango.io.digest.Sha256; import tango.io.digest.Sha512; import tango.io.digest.Tiger; // Read string from the command line and generate a hash // - The first parameter is the desired hash // - The rest of the command line is the string // // Format: cipher hash string to hash goes here // where: // 'hash' can be crc32, md2, md4, md5, sha0, sha1, sha256, sha512, tiger // // Output the resulting digest as a hex string int main(char[][] args) { Digest digest; char[] name = args[1]; char[] text; for( int i=2; i<args.length-1; i++ ) { text ~= args[i]; text ~= " "; } text ~= args[length-1]; Cout( "Calculating " ) (name) ( " hash of '") (text) ("'"). newline; try { digest = MakeADigest(name); digest.update(text); Cout( digest.hexDigest() ).newline; } catch( Exception e ) { Cout( "Exception occured ") (e.toString()).newline; } return( 0 ); } Digest MakeADigest( char[] desiredDigest ) { Digest c; switch( desiredDigest ) { case "crc32": c = new Crc32; break; case "md2": c = new Md2; break; case "md4": c = new Md4; break; case "md5": c = new Md5; break; case "sha0": c = new Sha0; break; case "sha1": c = new Sha1; break; case "sha256": c = new Sha256; break; case "sha512": c = new Sha512; break; case "tiger": c = new Tiger; break; } return( c ); }