protected override byte[] HashFinal()
{
byte[] md5Hash, sha1Hash;
byte[] pad1 = new byte[48];
byte[] pad2 = new byte[48];
for (int i=0; i<48; i++) {
pad1[i] = 0x36;
pad2[i] = 0x5C;
}
/* Inner MD5 hash */
_md5.TransformBlock(KeyValue, 0, KeyValue.Length, KeyValue, 0);
_md5.TransformFinalBlock(pad1, 0, 48);
md5Hash = _md5.Hash;
/* Inner SHA1 hash */
_sha1.TransformBlock(KeyValue, 0, KeyValue.Length, KeyValue, 0);
_sha1.TransformFinalBlock(pad1, 0, 40);
sha1Hash = _sha1.Hash;
/* Outer MD5 hash */
_md5.Initialize();
_md5.TransformBlock(KeyValue, 0, KeyValue.Length, KeyValue, 0);
_md5.TransformBlock(pad2, 0, 48, pad2, 0);
_md5.TransformFinalBlock(md5Hash, 0, 16);
md5Hash = _md5.Hash;
/* Outer SHA1 hash */
_sha1.Initialize();
_sha1.TransformBlock(KeyValue, 0, KeyValue.Length, KeyValue, 0);
_sha1.TransformBlock(pad2, 0, 40, pad2, 0);
_sha1.TransformFinalBlock(sha1Hash, 0, 20);
sha1Hash = _sha1.Hash;
byte[] verifyData = new byte[36];
Buffer.BlockCopy(md5Hash, 0, verifyData, 0, 16);
Buffer.BlockCopy(sha1Hash, 0, verifyData, 16, 20);
return verifyData;
}