/* * kbiffcrypt.cpp * Copyright (C) 2005 Michael Hendricks * * This file contains the implementation of the functions in * the KBiffCrypt namespace. * * $Id$ */ #include "kbiffcrypt.h" #include #include TQString KBiffCrypt::hmac_md5(const TQString& text, const TQString& k) { // If the original key is too long, the new key will be a hash of // the original key. Then the new key might have NULL bytes in it, // so we can't use TQCString TQByteArray key = (TQByteArray)k.utf8(); KMD5 context; // for calculating MD5 sums KMD5::Digest digest; // intermediate storage for MD5 sums // inner and outer padding (key XORd with ipad and opad, respectively) TQByteArray k_ipad(64); TQByteArray k_opad(64); // if key is longer than 64 bytes reset it to key=MD5(key) if (key.size() > 64) { // cast to a TQCString because we don't want to hash the // trailing NULL byte KMD5 tctx((TQCString)key); key.duplicate((char*)tctx.rawDigest(), 16); } /* the HMAC-MD5 transform looks like this: * * MD5(K XOR opad, MD5(K XOR ipad, text)) * * where K is an n byte key * ipad is the byte 0x36 repeated 64 times * opad is the byte 0x5c repeated 64 times * text is the data being protected */ // XOR key with ipad and opad values, copying // the pad values after the key's end for (unsigned int i=0; i<64; i++) { if( i < key.size() ) { k_ipad[i] = key[i] ^ 0x36; k_opad[i] = key[i] ^ 0x5c; } else { k_ipad[i] = 0x36; k_opad[i] = 0x5c; } } // perform inner MD5 context.reset(); // init context for 1st pass context.update(k_ipad); // start with inner pad context.update(text.utf8()); // then text of datagram context.rawDigest(digest); // finish up 1st pass // perform outer MD5 context.reset(); // init context for 2nd pass context.update(k_opad); // start with outer pad context.update(digest, 16); // then results of 1st hash return context.hexDigest(); // finish up 2nd pass and return }