Collisions in Hash Signatures

The MD2 and MD4 hashing functions were developed by Prof Ronald Rivest in 1989 and 1990, respectively. They both produce a 128-bit hash, but have been shown be vulnerable to attack.

A collision occurs when two different inputs produce the same hash signature. The following shows two examples where two different input values produce the same hash signature, where the differences between the two values is defined in bold. In this case the characters produced by the data are non-printing ones, so the data is defined as a hex string (which is converted into a byte array based on the hex values). With this a hex value is used to represent the data, where a 0x is inserted into the data and passed into this Web page:

  • Try “839c7a4d7a92cb5678a5d5b9eea5a7573c8a74deb366c3dc20a083b69f5d2a3bb3719dc69891e9f95e809fd7e8b23ba6318edd45e51fe39708bf9427e9c3e8b9“. Try!, which should give a MD4 hash of: 4d7e6a1defa93d2dde05b45d864c429b Check
  • Try “839c7a4d7a92cbd678a5d529eea5a7573c8a74deb366c3dc20a083b69f5d2a3bb3719dc69891e9f95e809fd7e8b23ba6318edc45e51fe39708bf9427e9c3e8b9“. Try!, which should give a MD4 hash of: 4d7e6a1defa93d2dde05b45d864c429b Check
  • Try “839c7a4d7a92cb5678a5d5b9eea5a7573c8a74deb366c3dc20a083b69f5d2a3bb3719dc69891e9f95e809fd7e8b23ba6318edd45e51fe39740c213f769cfb8a7“. Try!, which should give a MD4 hash of: c6f3b3fe1f4833e0697340fb214fb9ea Check
  • Try “839c7a4d7a92cbd678a5d529eea5a7573c8a74deb366c3dc20a083b69f5d2a3bb3719dc69891e9f95e809fd7e8b23ba6318edc45e51fe39740c213f769cfb8a7“. Try!, which should give a MD4 hash of: c6f3b3fe1f4833e0697340fb214fb9ea Check

I have outlined it in the following presentation:

Source Code

In the following example the Bouncy Castle libraries are used to generate MD2 and MD5:

using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Crypto.Paddings;

public void checkMD(string message, bool hex)
        {

            byte[] data = null;
            byte[] o = null;

            if (message == null) return;

            System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();

            if (hex == false)
                data = encoding.GetBytes(message);
            else data = StringToByteArray(message);

            Org.BouncyCastle.Crypto.Digests.MD2Digest w4 = new Org.BouncyCastle.Crypto.Digests.MD2Digest();

            w4.Reset(); w4.BlockUpdate(data, 0, data.Length);

            o = new byte[w4.GetDigestSize()];
            w4.DoFinal(o, 0); md2 = Global.ByteToString(o);

            Org.BouncyCastle.Crypto.Digests.MD4Digest w5 = new Org.BouncyCastle.Crypto.Digests.MD4Digest();

            w5.Reset(); w5.BlockUpdate(data, 0, data.Length);

            o = new byte[w5.GetDigestSize()];
            w5.DoFinal(o, 0); md4 = Global.ByteToString(o);

            Org.BouncyCastle.Crypto.Digests.NullDigest w6 = new Org.BouncyCastle.Crypto.Digests.NullDigest();

            w6.Reset(); w6.BlockUpdate(data, 0, data.Length);

            o = new byte[w6.GetDigestSize()];
            w6.DoFinal(o, 0); nullhash = Global.ByteToString(o);        }

Cisco Simulators using ASP.NET MVC

Outline

Over the years, I created the NetworkSims ProfSims Cisco Simulators which run under Microsoft .NET. Unfortunately it has been difficult to update, and also difficult for it to run on range of computer systems. I have been working with ASP.NET MVC, and have found it to be amazing in terms of creating content which clearly separates the user interface from the rest of the software.

Here is what my simulator used to look like:

New ASP.NET Version

ASP.NET MVC allows you to separate the Model (the data), the Controller (the middle part), and View (the user interface). It took a while to get the simulator to work on a range of browser, but here’s the result:

Capturing keystrokes

It is quite a challenge to capture keystrokes, especially on different browsers. First we setup the first time screen:

<script type="text/javascript">
    var part1 = "System Bootstrap, Version 11.0(10c)XB2, PLATFORM SPECIFIC RELEASE SOFTWARE (fc1)\nCopyright (c) 1986-1998 by cisco Systems\n2500 processor with 2048 Kbytes of main memory\n\nNotice: NVRAM invalid, possibly due to write erase.\n\nF3: 6700084+88348+451572 at 0x3000060\n\n              Restricted Rights Legend\n\nUse, duplication, or disclosure by the Government is\nsubject to restrictions as set forth in subparagraph\n(c) of the Commercial Computer Software - Restricted\nRights clause at FAR sec. 52.227-19 and subparagraph\n(c) (1) (ii) of the Rights in Technical Data and Computer\nSoftware clause at DFARS sec. 252.227-7013.\n\n           cisco Systems, Inc.\n           170 West Tasman Drive\n           San Jose, California 95134-1706\n\nCisco Internetwork Operating System Software \nIOS (tm) 2500 Software (C2500-D-L), Version 12.0(4), RELEASE SOFTWARE (fc1)\nCopyright (c) 1986-1999 by cisco Systems, Inc.\nCompiled Wed 14-Apr-99 21:21 by ccai\nImage text-base: 0x03037C88, data-base: 0x00001000\n\ncisco 2500 (68030) processor (revision L) with 2048K/2048K bytes of memory.\nProcessor board ID 13583483, with hardware revision 00000000\nBridging software.\nX.25 software, Version 3.0.0.\n2 Ethernet/IEEE 802.3 interface(s)\n2 Serial network interface(s)\n32K bytes of non-volatile configuration memory.\n8192K bytes of processor board System flash (Read ONLY)\n\nPress RETURN to get started! ";
    var prompt = "> ";

    var console = document.getElementById("console");

    var command = "";

    xmlHttp = new XMLHttpRequest();
    xmlHttp.open("POST", "/Cisco/ProcessCommandR", false);
    xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xmlHttp.send("command=" + command.trim());

    var response = xmlHttp.responseText;

    var n = response.split("||");
    chall.value = n[1];
    response = n[0];


    console.value = console.value + part1;

    if (n.length > 1) details.value = n[2];


    console.value = console.value + prompt;
    selectEnd(console);
    console.focus();

which calls the MVC method of ProcessCommandR() within the CiscoController, and then puts the output to console.

We can then capture the key events with:

    document.getElementById("console").onkeydown =
		function (event) {

		    if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1) return true;

		    event = event || window.event;

		    var e = event.keyCode;

		    if (e.which == 90 && e.ctrlKey) {

		        return true;
		    }

		    if (e == 8) {


		        pos = console.value.lastIndexOf('#');
		        pos2 = console.value.lastIndexOf('>');


		        if ((pos == console.value.length - 2) || (pos2 == console.value.length - 2)) return false;

		        else return true;
		    }

		    else if (e == 27) {

		        var command = getCommand();

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/ProcessCommandR", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("command=" + command.trim());

		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];

		        console.value = response;


		        selectEnd(console);
		        return false;
		    }




		}

		document.getElementById("console").onkeypress =
		function (event) {


		    event = event || window.event;

		    var e = event.keyCode;
		    // tab key
		    if (e == 9) {
		        var command = getCommand();

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/ProcessCommandREsc", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("command=" + command.trim());
		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];

		        if (response.length > 0) {
		            console.value = console.value.slice(0, console.value.lastIndexOf(" "));
		            console.value = console.value + " " + response;
		        } else console.value = console.value;

		        selectEnd(console);
		        return false;

		    }
		    if (e == 8) {


		        pos = console.value.lastIndexOf('#');
		        pos2 = console.value.lastIndexOf('>');


		        if ((pos == console.value.length - 2) || (pos2 == console.value.length - 2)) return false;
		        else return true;
		    }
		    else if (e == 27) {

		        var command = getCommand();

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/ProcessCommandR", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("command=" + command.trim());

		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];

		        console.value = response;


		        selectEnd(console);
		        return false;
		    }
		    // Up Arrow
		    else if (e == 38) {

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/Up", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("");

		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];

		        console.value = response;


		        selectEnd(console);
		        return false;
		    }
		    else if (e == 40) {

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/Down", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("");

		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];


		        console.value = response;


		        selectEnd(console);
		        return false;
		    }
		    else if (event.charCode == 63) {
		        var command = getCommand() + "?";

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/ProcessCommandR", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("command=" + command.trim());

		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];

		        if (response.length > 0) console.value = console.value + "?\n" + response;

		        console.value = console.value;

		        selectEnd(console);
		        return false;
		    }

		    else if (e == 13) {
		        var command = getCommand();

		        xmlHttp = new XMLHttpRequest();
		        xmlHttp.open("POST", "/Cisco/ProcessCommandR", false);
		        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		        xmlHttp.send("command=" + command.trim());

		        var response = xmlHttp.responseText;

		        var n = response.split("||");
		        chall.value = n[1];
		        response = n[0];

		        if (response.length > 0) console.value = console.value + "\n" + response;

		        if (n.length>1) details.value = n[2];

		        console.value = console.value;

		        selectEnd(console);
		        return false;
		    }

		}

    document.getElementById("console").onclick = function (event) { checkCursorPosition(event); }
    document.getElementById("console").onselectstart = function (event) { checkCursorPosition(event); }
    document.getElementById("console").onkeyup = function (event) { checkCursorPosition(event); }

Pop-up challenge

You will notice that I’ve used tabs for different windows. For this, I’ve created a pop-up window for the challenge:

 @(Html.Kendo().Window()
    .Name("ChallengeWindow")
    .Title("Challenge") 
         .Content(@<div>@</div@>
	)
    .Modal(false)
    .Draggable(true)
    .Width(450)
    .Scrollable(true)
            .Animation(true)
            
)

SHA-3

Outline

SHA-3 was known as Keccak and is a hash function designed by Guido Bertoni, Joan Daemen, Michaël Peeters, and Gilles Van Assche. MD5 and SHA-0 have been shown to be susceptible to attacks, along with theoretical attacks on SHA-1. NIST thus defined there was a need for a new hashing method which did not use the existing methods for hashing, and setup a competition for competing algorithms. In October 2012, Keccak won the NIST hash function competition, and is proposed as the SHA-3 standard. It should be noted that it is not replacement SHA-2, which is currently a secure methods. Overall Keccak uses the sponge construction where the message blocks are XORed into the initial bits of the state, and then invertibly permuted.

I tried many libraries for this, but this is the only one which actually gives the right answer:

http://nuget.org/packages/SHA3/

Web page

One standard test is:

The quick brown fox jumps over the lazy dog

which should give:

310AEE6B30C47350576AC2873FA89FD190CDC488442F3EF654CF23FE

Here is an example:

The quick brown …

Presentation

Playfair

Playfair is a great little code, and uses a 5×5 matrix, where we add the key at the start, and then place the rest of the letters (without repeating any). Next we take the plain text two characters at a time, and then draw a rectangle around then, and the other letters which bound the rectangle are then used. For example with a key of “playfair example” Theory

P 	L 	A 	Y 	F 
I 	R 	E 	X 	M 
B 	C 	D 	G 	H 
K 	N 	O 	Q 	S 
T 	U 	V 	W 	Z

For example if we use:

hide the gold in the tree stump

with a key:

playfairexample

We get a matrix of:

playf
irexm
bcdgh
knoqs
tuvwz

The first step is to split into two character strings:

hi de th eg ol di nt he tr ee st um p

First “hi” gives:

-----
i---m
b---h
-----
-----

to give “bm”. The final mapping is then:

bm od zb xd na be ku dm ui xm mo uv if

Presentation

http://www.asecuritysite.com/Coding/playfair?word=Hide%20the%20gold%20in%20the%20tree%20stump%2Cplayfairexample

There are more details at:

http://www.asecuritysite.com/Coding/playfair