Export (0) Print
Expand All
This topic has not yet been rated - Rate this topic

MACTripleDES Class

Computes a Message Authentication Code (MAC) using TripleDES for the input data CryptoStream.

Namespace: System.Security.Cryptography
Assembly: mscorlib (in mscorlib.dll)

[ComVisibleAttribute(true)] 
public ref class MACTripleDES : public KeyedHashAlgorithm
/** @attribute ComVisibleAttribute(true) */ 
public class MACTripleDES extends KeyedHashAlgorithm
ComVisibleAttribute(true) 
public class MACTripleDES extends KeyedHashAlgorithm
Not applicable.

A MAC can be used to determine whether a message sent over an insecure channel has been tampered with, provided that the sender and receiver share a secret key. The sender computes the MAC for the original data, and sends both as a single message. The receiver recomputes the MAC on the received message, and checks that the computed MAC matches the transmitted MAC.

Any change to the data or the MAC will result in a mismatch, because knowledge of the secret key is required to change the message and reproduce the correct MAC. Therefore, if the codes match, the message is authenticated.

MACTripleDES uses a key of length 16 or 24 bytes, and produces a hash sequence of length 8 bytes.

The following section contains code examples. The first example computes the MAC for data using the TripleDES hash algorithm and stores it in result. The second example demonstrates how to use each member of the MACTripleDES class.

Example #1

This example assumes that there is a predefined constant DATA_SIZE.

array<Byte>^data = gcnew array<Byte>(DATA_SIZE);
array<Byte>^key = gcnew array<Byte>(24);
MACTripleDES^ mac3des = gcnew MACTripleDES( key );
array<Byte>^result = mac3des->ComputeHash( data );

ubyte data[] = new ubyte[dataSize];
ubyte key[] = new ubyte[24];
MACTripleDES mac3des = new MACTripleDES(key);
ubyte result[] = mac3des.ComputeHash(data);

Example #2


using namespace System;
using namespace System::IO;
using namespace System::Text;
using namespace System::Collections;
using namespace System::Security::Cryptography;

namespace CryptographySample
{
    ref class DESSample
    {
    public:

        static void TestDES();

    private:
        static void EncodeNothing();
        static void EncodeStream();
        static void EncodeMessage();
        static array<Byte>^ EncodeBytes(array<Byte>^ sourceBytes);
        static void SummarizeMAC(MACTripleDES^ macTriple, 
            String^ description);
    };

    void DESSample::TestDES()
    {
        EncodeNothing();
        EncodeMessage();
        EncodeStream();
        Console::WriteLine("This sample completed successfully; "
            "press Enter to exit.");
        Console::ReadLine();
    }

    // Compute the hash for an empty array; summarize the properties.
    void DESSample::EncodeNothing()
    {
        MACTripleDES^ macTriple = gcnew MACTripleDES;

        macTriple->Initialize();

        array<Byte>^ key = gcnew array<Byte>(24);
        RandomNumberGenerator::Create()->GetBytes(key);
        macTriple->Key = key;
        macTriple->ComputeHash(gcnew array<Byte>(1024));
        SummarizeMAC(macTriple, "MACTripleDES after initialization.");
    }

    // Compute the hash for a MACTripleDES that has transformed a
    // file stream.
    void DESSample::EncodeStream()
    {
		array<Byte>^ keyData = gcnew array<Byte>(24);
        RandomNumberGenerator::Create()->GetBytes(keyData);
        MACTripleDES^ macTriple = gcnew MACTripleDES(keyData);

        String^ filePath = (String::Concat(
            System::IO::Directory::GetCurrentDirectory(), 
            "\\members.txt"));
        try
        {
            FileStream fileStream(filePath,
                FileMode::Open, FileAccess::Read);

            macTriple->ComputeHash(%fileStream);

            SummarizeMAC(macTriple, 
                "MACTripleDES after encoding a file stream.");
        }
        catch (FileNotFoundException^ ex) 
        {
            Console::WriteLine("Specified path was not found: {0}", 
                filePath);
            __assume(ex);
        }

    }


    // Compute the hash for a MACTripleDES that has transformed a
    // byte array.
    void DESSample::EncodeMessage()
    {
        Encoding^ encodingASCII = Encoding::ASCII;
        array<Byte>^ keyData = gcnew array<Byte>(24);
        RandomNumberGenerator::Create()->GetBytes(keyData);
        MACTripleDES^ macTriple = gcnew MACTripleDES(keyData);

        String^ message = "Encoding is fun!";
        array<Byte>^ encodedMessage = EncodeBytes(
            encodingASCII->GetBytes(message));
        macTriple->ComputeHash(encodedMessage);

        SummarizeMAC(macTriple, 
            "MACTripleDES after encoding a message.");
    }


    // Transform the byte array using MacTripleDES,
    // and then summarize its properties.
    array<Byte>^ DESSample::EncodeBytes(array<Byte>^ sourceBytes)
    {
        int currentPosition = 0;
        array<Byte>^ targetBytes = gcnew array<Byte>(1024);
        int sourceByteLength = sourceBytes->Length;

        // Create an encryptor with a random key and the TripleDES
        // class name.
        array<Byte>^ key = gcnew array<Byte>(24);
        RandomNumberGenerator::Create()->GetBytes(key);
        String^ tripleName = "System.Security.Cryptography.TripleDES";
        MACTripleDES^ macTriple = gcnew MACTripleDES(tripleName, key);

        // Retrieve the block size to read the bytes.
        int inputBlockSize = macTriple->InputBlockSize;

        try
        {

            // Determine if multiple blocks can be transformed.
            if (macTriple->CanTransformMultipleBlocks)
            {
                int bytesRead = 0;
                while (sourceByteLength - currentPosition >= 
                    inputBlockSize)
                {
                    // Transform the bytes from the currentposition in 
                    // the sourceBytes array, writing the bytes to the 
                    // targetBytes array.
                    bytesRead = 
                        macTriple->TransformBlock(sourceBytes, 
                        currentPosition, inputBlockSize, targetBytes, 
                        currentPosition);
                    // Advance the current position in the
                    // sourceBytes array.
                    currentPosition += bytesRead;
                }

                // Transform the final block of bytes.
                array<Byte>^ finalBytes = 
                    macTriple->TransformFinalBlock(sourceBytes, 
                    currentPosition, sourceByteLength - 
                    currentPosition);
                // Copy the contents of the finalBytes array to the
                // targetBytes array.
                finalBytes->CopyTo(targetBytes, currentPosition);
            }
        }
        catch (ArgumentException^ ex) 
        {
            Console::WriteLine("Caught unexpected exception:{0}", ex);
        }

        // Determine if the current transform can be reused.
        if (!macTriple->CanReuseTransform)
        {
            // Free up any used resources.
            macTriple->Clear();
        }

        // Find the length of valid bytes (those without zeros).
        int i = 0;
        for each (Byte byte in targetBytes)
        {
            if (byte == 0)
                break;
            i++;
        }

        // Compute the hash based on the valid bytes in the array.
        macTriple->ComputeHash(targetBytes, 0, i);

        SummarizeMAC(macTriple, "MACTripleDES after computing "
            "the hash for the specified region of the byte array.");

        // Create a new array with the number of valid bytes.
        array<Byte>^ returnedArray = gcnew array<Byte>(i);
        Array::Copy(targetBytes, returnedArray, i);
        return returnedArray;
    }


    // Write a summary of the specified MACTripleDES to the console.
    void DESSample::SummarizeMAC(MACTripleDES^ macTriple, 
        String^ description)
    {
        Encoding^ encASCIIEncoding = Encoding::ASCII;

        String^ classDescription = macTriple->ToString();

        array<Byte>^ computedHash = macTriple->Hash;

        int hashSize = macTriple->HashSize;

        int outputBlockSize = macTriple->OutputBlockSize;

        // Retrieve the key used in the hash algorithm.
        array<Byte>^ key = macTriple->Key;

        Console::WriteLine("\n**********************************");
        Console::WriteLine(classDescription);
        Console::WriteLine(description);
        Console::WriteLine("----------------------------------");
        Console::WriteLine("The size of the computed hash : {0}", 
            hashSize);
        Console::WriteLine("The key used in the hash algorithm : {0}", 
            encASCIIEncoding->GetString(key));
        Console::WriteLine("The value of the computed hash : {0}", 
            encASCIIEncoding->GetString(computedHash));
    }
}

using namespace CryptographySample;

int main()
{
    DESSample::TestDES();
}

//
// This sample produces the following output:
//
// **********************************
// System.Security.Cryptography.MACTripleDES
// MACTripleDES after initialization.
// ----------------------------------
// The size of the computed hash : 64
// The key used in the hash algorithm : +Lnf>j%?4?7?V???K?Jv_AcB
// The value of the computed hash : YH>|*DX;
// 
// **********************************
// System.Security.Cryptography.MACTripleDES
// MACTripleDES after computing the hash for the specified region 
// of the byte array.
// ----------------------------------
// The size of the computed hash : 64
// The key used in the hash algorithm : >
// -?h?v?tF*r`f%V?t`.jS50
// The value of the computed hash : :?9q1$b?
// 
// **********************************
// System.Security.Cryptography.MACTripleDES
// MACTripleDES after encoding a message.
// ----------------------------------
// The size of the computed hash : 64
// The key used in the hash algorithm : ?rK>~6>?xy-R? r7s,_kCP{}
// The value of the computed hash : bG?*UO?S
// 
// **********************************
// System.Security.Cryptography.MACTripleDES
// MACTripleDES after encoding a file stream.
// ----------------------------------
// The size of the computed hash : 64
// Yv)???rTY?}?T?/\FOI?D$sh algorithm :
// The value of the computed hash : K??T]QgN
// This sample completed successfully; press Enter to exit.

import System.*;
import System.IO.*;
import System.Text.*;
import System.Collections.*;
import System.Security.Cryptography.*;

class Class1
{
    /** @attribute STAThread()
     */
    public static void main(String[] args)
    {
        EncodeNothing();
        EncodeMessage();
        EncodeStream();
        Console.WriteLine("This sample completed successfully; " 
            + "press Enter to exit.");
        Console.ReadLine();
    } //main

    // Compute the hash for an empty array; summarize the properties.
    private static void EncodeNothing()
    {
        MACTripleDES macTriple = new MACTripleDES();

        macTriple.Initialize();

        ubyte key[] = new ubyte[24];
        RandomNumberGenerator.Create().GetBytes(key);
        macTriple.set_Key(key);
        macTriple.ComputeHash(new ubyte[1024]);
        SummarizeMAC(macTriple, "MACTripleDES after initialization.");
    } //EncodeNothing

    // Compute the hash for a MACTripleDES that has transformed a
    // file stream.
    private static void EncodeStream()
    {
        ubyte keyData[] = new ubyte[24];
        RandomNumberGenerator.Create().GetBytes(keyData);
        MACTripleDES macTriple = new MACTripleDES(keyData);

        String filePath = System.IO.Directory.GetCurrentDirectory() 
            + "\\members.txt";
        try {
            FileStream fileStream = new FileStream(filePath, FileMode.Open, 
                FileAccess.Read);
            macTriple.ComputeHash(fileStream);
            SummarizeMAC(macTriple, 
                "MACTripleDES after encoding a file stream.");
        }
        catch (FileNotFoundException ex) {
            Console.WriteLine("Specified path was not found: " + filePath);
        }
    } //EncodeStream

    // Compute the hash for a MACTripleDES that has transformed a
    // byte array.
    private static void EncodeMessage()
    {
        ubyte keyData[] = new ubyte[24];
        RandomNumberGenerator.Create().GetBytes(keyData);
        MACTripleDES macTriple = new MACTripleDES(keyData);
        String message = "Encoding is fun!";
        ubyte encodedMessage[] = EncodeBytes(Encoding.get_ASCII().
            GetBytes(message));
        macTriple.ComputeHash(encodedMessage);
        SummarizeMAC(macTriple, "MACTripleDES after encoding a message.");
    } //EncodeMessage

    // Transform the byte array using MacTripleDES,
    // and then summarize its properties.
    private static ubyte[] EncodeBytes(ubyte sourceBytes[])
    {
        int currentPosition = 0;
        ubyte targetBytes[] = new ubyte[1024];
        int sourceByteLength = sourceBytes.get_Length();
        // Create an encryptor with a random key and the TripleDES
        // class name.
        ubyte key[] = new ubyte[24];
        RandomNumberGenerator.Create().GetBytes(key);
        String tripleDesName = "System.Security.Cryptography.TripleDES";
        MACTripleDES macTriple = new MACTripleDES(tripleDesName, key);

        // Retrieve the block size to read the bytes.
        int inputBlockSize = macTriple.get_InputBlockSize();
        try {
            // Determine if multiple blocks can be transformed.
            if (macTriple.get_CanTransformMultipleBlocks()) {
                int numBytesRead = 0;
                while (sourceByteLength - currentPosition >= inputBlockSize) {
                    // Transform the bytes from the currentposition in the
                    // sourceBytes array, writing the bytes to the 
                    // targetBytes array.
                    numBytesRead = macTriple.TransformBlock(sourceBytes, 
                        currentPosition, inputBlockSize, targetBytes, 
                        currentPosition);
                    // Advance the current position in the
                    // sourceBytes array.
                    currentPosition += numBytesRead;
                }
                // Transform the final block of bytes.
                ubyte finalBytes[] = macTriple.TransformFinalBlock(sourceBytes, 
                    currentPosition, sourceByteLength - currentPosition);
                // Copy the contents of the finalBytes array to the
                // targetBytes array.
                finalBytes.CopyTo(targetBytes, currentPosition);
            }
        }
        catch (System.Exception ex) {
            Console.WriteLine("Caught unexpected exception:" + ex.ToString());
        }
        // Determine if the current transform can be reused.
        if (!(macTriple.get_CanReuseTransform())) {
            // Free up any used resources.
            macTriple.Clear();
        }
        // Find the length of valid bytes (those without zeros).
        IEnumerator enum1 = targetBytes.GetEnumerator();
        int i = 0;
        while (enum1.MoveNext()) {
            if (enum1.get_Current().ToString().Equals("0")) {
                break;
            }
            i++;
        }
        // Compute the hash based on the valid bytes in the array.
        macTriple.ComputeHash(targetBytes, 0, i);

        SummarizeMAC(macTriple, "MACTripleDES after computing the hash " 
            + "for the specified region of the byte array.");
        // Create a new array with the number of valid bytes.
        ubyte returnedArray[] = new ubyte[i];
        for (int j = 0; j < i; j++) {
            returnedArray.set_Item(j, targetBytes.get_Item(j));
        }
        return returnedArray;
    } //EncodeBytes

    // Write a summary of the specified MACTripleDES to the console.
    private static void SummarizeMAC(MACTripleDES macTriple, 
        String description)
    {
        String classDescription = macTriple.ToString();

        ubyte computedHash[] = macTriple.get_Hash();

        int hashSize = macTriple.get_HashSize();

        int outputBlockSize = macTriple.get_OutputBlockSize();

        // Retrieve the key used in the hash algorithm.
        ubyte key[] = macTriple.get_Key();

        Console.WriteLine("\n**********************************");
        Console.WriteLine(classDescription);
        Console.WriteLine(description);
        Console.WriteLine("----------------------------------");
        Console.WriteLine("The size of the computed hash : " + hashSize);
        Console.WriteLine("The key used in the hash algorithm : " 
            + Encoding.get_ASCII().GetString(key));
        Console.WriteLine("The value of the computed hash : " 
            + Encoding.get_ASCII().GetString(computedHash));
    } //SummarizeMAC
} //Class1

Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe.

Windows 98, Windows Server 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Media Center Edition, Windows XP Professional x64 Edition, Windows XP SP2, Windows XP Starter Edition

The Microsoft .NET Framework 3.0 is supported on Windows Vista, Microsoft Windows XP SP2, and Windows Server 2003 SP1.

.NET Framework

Supported in: 3.0, 2.0, 1.1, 1.0
Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback

Community Additions

ADD
Show:
© 2014 Microsoft. All rights reserved.