How to get source from MD5 hash

Posted on 2011-09-02
Last Modified: 2013-12-17
I have created a MD5 hash from the following code.  How do I get the original source data from the MD5 hash?
//----------------------    create hash of renewal date    --------------------------|
        public string createHashDate() {

            string sSourceData;
            byte[] tmpSource;
            byte[] tmpHash;

            sSourceData = DateTime.Today.ToShortDateString() + "renewal";

            //Create a byte array from source data.
            tmpSource = ASCIIEncoding.ASCII.GetBytes(sSourceData);

            //Compute hash based on source data.
            tmpHash = new MD5CryptoServiceProvider().ComputeHash(tmpSource);

            string renewalDate = ByteArrayToString(tmpHash);

            return renewalDate;

Open in new window

Question by:rmmarsh
  • 5
  • 2
  • 2
LVL 12

Assisted Solution

by:Wouter Boevink
Wouter Boevink earned 500 total points
ID: 36473821
Hashing is a one way algoritm you can't get the original source from a hash code.
LVL 12

Expert Comment

by:Wouter Boevink
ID: 36473843
A good example for the use of hashing are password. For security reasons you might not want to store passwords, in that case you compute a hash and store the hash value. When a user submits has password you calculate the hash again and compare in with the one you stored.

Author Comment

ID: 36473866
That presents a quandary for me... I have a date (license renewal date) that I want to encrypt so it can't be tampered with.  I need to be able to get to that encrypted date so I can determine if it's time for renewal.

What should I be using rather than a hash?
Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

LVL 15

Expert Comment

ID: 36473883
This code is intended to be not reversible.

It is used when security is important.

You can compute a Hash code for a Password, store the computed hash on a database privileges table an compare the value to computed hash code from other key.

When Hash computed matches, then you grant access.

When user lost password, Admin can reset the password, but it can´nt get the original password.
LVL 12

Accepted Solution

Wouter Boevink earned 500 total points
ID: 36473898
Use an encryption algoritm

Encrypting data:
Decrypting data:

using System; 
using System.Data; 
using System.Security.Cryptography; 
using System.IO; 
public class SimpleAES 
    // Change these keys 
    private byte[] Key = { 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 }; 
    private byte[] Vector = { 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 }; 
    private ICryptoTransform EncryptorTransform, DecryptorTransform; 
    private System.Text.UTF8Encoding UTFEncoder; 
    public SimpleAES() 
        //This is our encryption method 
        RijndaelManaged rm = new RijndaelManaged(); 
        //Create an encryptor and a decryptor using our encryption method, key, and vector. 
        EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector); 
        DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector); 
        //Used to translate bytes to text and vice versa 
        UTFEncoder = new System.Text.UTF8Encoding(); 
    /// -------------- Two Utility Methods (not used but may be useful) ----------- 
    /// Generates an encryption key. 
    static public byte[] GenerateEncryptionKey() 
        //Generate a Key. 
        RijndaelManaged rm = new RijndaelManaged(); 
        return rm.Key; 
    /// Generates a unique encryption vector 
    static public byte[] GenerateEncryptionVector() 
        //Generate a Vector 
        RijndaelManaged rm = new RijndaelManaged(); 
        return rm.IV; 
    /// ----------- The commonly used methods ------------------------------     
    /// Encrypt some text and return a string suitable for passing in a URL. 
    public string EncryptToString(string TextValue) 
        return ByteArrToString(Encrypt(TextValue)); 
    /// Encrypt some text and return an encrypted byte array. 
    public byte[] Encrypt(string TextValue) 
        //Translates our text value into a byte array. 
        Byte[] bytes = UTFEncoder.GetBytes(TextValue); 
        //Used to stream the data in and out of the CryptoStream. 
        MemoryStream memoryStream = new MemoryStream(); 
         * We will have to write the unencrypted bytes to the stream, 
         * then read the encrypted result back from the stream. 
        #region Write the decrypted value to the encryption stream 
        CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write); 
        cs.Write(bytes, 0, bytes.Length); 
        #region Read encrypted value back out of the stream 
        memoryStream.Position = 0; 
        byte[] encrypted = new byte[memoryStream.Length]; 
        memoryStream.Read(encrypted, 0, encrypted.Length); 
        //Clean up. 
        return encrypted; 
    /// The other side: Decryption methods 
    public string DecryptString(string EncryptedString) 
        return Decrypt(StrToByteArray(EncryptedString)); 
    /// Decryption when working with byte arrays.     
    public string Decrypt(byte[] EncryptedValue) 
        #region Write the encrypted value to the decryption stream 
        MemoryStream encryptedStream = new MemoryStream(); 
        CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write); 
        decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length); 
        #region Read the decrypted value from the stream. 
        encryptedStream.Position = 0; 
        Byte[] decryptedBytes = new Byte[encryptedStream.Length]; 
        encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length); 
        return UTFEncoder.GetString(decryptedBytes); 
    /// Convert a string to a byte array.  NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so). 
    //      System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); 
    //      return encoding.GetBytes(str); 
    // However, this results in character values that cannot be passed in a URL.  So, instead, I just 
    // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100). 
    public byte[] StrToByteArray(string str) 
        if (str.Length == 0) 
            throw new Exception("Invalid string value in StrToByteArray"); 
        byte val; 
        byte[] byteArr = new byte[str.Length / 3]; 
        int i = 0; 
        int j = 0; 
            val = byte.Parse(str.Substring(i, 3)); 
            byteArr[j++] = val; 
            i += 3; 
        while (i < str.Length); 
        return byteArr; 
    // Same comment as above.  Normally the conversion would use an ASCII encoding in the other direction: 
    //      System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding(); 
    //      return enc.GetString(byteArr);     
    public string ByteArrToString(byte[] byteArr) 
        byte val; 
        string tempStr = ""; 
        for (int i = 0; i <= byteArr.GetUpperBound(0); i++) 
            val = byteArr[i]; 
            if (val < (byte)10) 
                tempStr += "00" + val.ToString(); 
            else if (val < (byte)100) 
                tempStr += "0" + val.ToString(); 
                tempStr += val.ToString(); 
        return tempStr; 

Open in new window


Author Closing Comment

ID: 36473926
Thank you... I appreciate it!
LVL 12

Expert Comment

by:Wouter Boevink
ID: 36473932
Or use an simple XOREncryption

using System;
using System.Collections.Generic;
using System.Text;

namespace SimpleXOREncryption
    public static class EncryptorDecryptor
        public static int key = 129;

        public static string EncryptDecrypt(string textToEncrypt)
            StringBuilder inSb = new StringBuilder(textToEncrypt);
            StringBuilder outSb = new StringBuilder(textToEncrypt.Length);
            char c;
            for (int i = 0; i < textToEncrypt.Length; i++)
                c = inSb[i];
                c = (char)(c ^ key);
            return outSb.ToString();

Open in new window

This will turn this string:


into this:


Another sample:

and back again, which in many cases, is "just enough" to keep things from prying eyes.
LVL 15

Expert Comment

ID: 36474166
You need use a class to encrypt / Decrypt (symetric).
You can use MD5, RijndaelManaged ...

When you create a new instance with this class, it creates a random Key.
To reuse this random Key, you need dump it.
the comented code, dumps the Cryptor.IV and Cryptor.Key. Comment previous lines before to use, then write your generated keys on Cryptor.IV an Cryptor.Key lines.

Note that there are also some methods to generate those from a secret Key, but I prefer random keys.

The encode and decode methods uses byte Arrays. To get a Byte array from your data, you can use a BinaryWriter (Encoding) and BinaryReader (Decoding).
Public Cryptor As New RijndaelManaged

  Sub New()
    Cryptor.IV = New Byte() {239, 175, 150, 40, 165, 166, 91, 192, 88, 162, 230, 151, 121, 79, 197, 68}
    Cryptor.Key = New Byte() {92, 222, 204, 131, 102, 60, 232, 72, 126, 208, 46, 102, 155, 235, 155, 57, 230, 65, 95, 203, 41, 148, 159, 167, 10, 185, 179, 164, 109, 40, 16, 67}
    'Generación inicial de claves aleatorias...
    'Dim bf As Byte() = Cryptor.IV, sb As New System.Text.StringBuilder(100)
    'For n As Integer = 0 To bf.Length - 1 : sb.Append(bf(n)).Append(","c) : Next : Debug.Print(sb.ToString)
    'bf = Cryptor.Key : sb.Length = 0
    'For n As Integer = 0 To bf.Length - 1 : sb.Append(bf(n)).Append(","c) : Next : Debug.Print(sb.ToString)

  Dim Ms As New MemoryStream(100)
  Dim bw As BinWriter = New BinWriter(Ms)
  Dim ctr As ICryptoTransform = Cryptor.CreateEncryptor()
  dim bf = Ms.ToArray  
  Dim Encrypted as byte() = ctr.TransformFinalBlock(bf, 0, bf.Length)
  dim br as New BinReader(New MemoryStream(Cryptor.CreateDecryptor().TransformFinalBlock(Encrypted, 0, Encrypted.Length)))
  dim MyPassword = br.readstring
  Dim MyDate = new date(br.ReadInt64)

Open in new window

LVL 12

Expert Comment

by:Wouter Boevink
ID: 36474233
@x77, not really contributing anything usefull by giving the same answer as the allready accepted solution. BTW md5 can't be uses.

Featured Post

How Do You Stack Up Against Your Peers?

With today’s modern enterprise so dependent on digital infrastructures, the impact of major incidents has increased dramatically. Grab the report now to gain insight into how your organization ranks against your peers and learn best-in-class strategies to resolve incidents.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

It seems a simple enough task, yet I see repeated questions asking how to do it: how to pass data between two forms. In this article, I will show you the different mechanisms available for you to do just that. This article is directed towards the .N…
This article shows how to deploy dynamic backgrounds to computers depending on the aspect ratio of display
I've attached the XLSM Excel spreadsheet I used in the video and also text files containing the macros used below.…

828 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question