How to get source from MD5 hash

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

rmmarshAsked:
Who is Participating?
 
Wouter BoevinkConnect With a Mentor MasterCommented:
Use an encryption algoritm

Encrypting data: http://msdn.microsoft.com/en-us/library/as0w18af.aspx
Decrypting data: http://msdn.microsoft.com/en-us/library/te15te69.aspx

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(); 
        rm.GenerateKey(); 
        return rm.Key; 
    } 
 
    /// Generates a unique encryption vector 
    static public byte[] GenerateEncryptionVector() 
    { 
        //Generate a Vector 
        RijndaelManaged rm = new RijndaelManaged(); 
        rm.GenerateIV(); 
        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); 
        cs.FlushFinalBlock(); 
        #endregion 
 
        #region Read encrypted value back out of the stream 
        memoryStream.Position = 0; 
        byte[] encrypted = new byte[memoryStream.Length]; 
        memoryStream.Read(encrypted, 0, encrypted.Length); 
        #endregion 
 
        //Clean up. 
        cs.Close(); 
        memoryStream.Close(); 
 
        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); 
        decryptStream.FlushFinalBlock(); 
        #endregion 
 
        #region Read the decrypted value from the stream. 
        encryptedStream.Position = 0; 
        Byte[] decryptedBytes = new Byte[encryptedStream.Length]; 
        encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length); 
        encryptedStream.Close(); 
        #endregion 
        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; 
        do 
        { 
            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(); 
            else 
                tempStr += val.ToString(); 
        } 
        return tempStr; 
    } 
}

Open in new window

0
 
Wouter BoevinkConnect With a Mentor MasterCommented:
Hashing is a one way algoritm you can't get the original source from a hash code.
0
 
Wouter BoevinkMasterCommented:
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.
0
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

 
rmmarshAuthor Commented:
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?
0
 
x77Commented:
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.
0
 
rmmarshAuthor Commented:
Thank you... I appreciate it!
0
 
Wouter BoevinkMasterCommented:
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);
                outSb.Append(c);
            }
            return outSb.ToString();
        }   
    }
}

Open in new window


This will turn this string:

server=myserver;database=mydatabase;uid=myuser;pwd=mypass;

into this:

òäó÷äó¼ìøòäó÷äóºåàõàãàòä¼ìøåàõàãàòäºôèå¼ìøôòäóºñöå¼ìøñàòòº

Another sample: http://www.eggheadcafe.com/tutorials/aspnet/f72c0f04-ec9c-40d8-a655-c706f8476fdb/aspnet-obfuscating-the-querystring.aspx

and back again, which in many cases, is "just enough" to keep things from prying eyes.
0
 
x77Commented:
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)
....
    


  'Encoding
    
  Dim Ms As New MemoryStream(100)
  Dim bw As BinWriter = New BinWriter(Ms)
  Dim ctr As ICryptoTransform = Cryptor.CreateEncryptor()
  bw.Write(MyPassword)
  bw.Write(MyDate.Ticks)
  .....
  dim bf = Ms.ToArray  
  Dim Encrypted as byte() = ctr.TransformFinalBlock(bf, 0, bf.Length)
  
  
  'Decoding
  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

0
 
Wouter BoevinkMasterCommented:
@x77, not really contributing anything usefull by giving the same answer as the allready accepted solution. BTW md5 can't be uses.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.