Tag: Ron Rivest

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);        }