LM Hash Calculator
[Return] This is an LM Hash Calculator. LM Hash is used in many version of Windows to
store user passwords that are fewer than 15 characters long. It is a fairly weak security implementation can be easily broken using standard dictionary lookups [Link]. More modern versions of Windows use SYSKEY to encrypt passwords [Link].
For example:
hashme gives: |
FA-91-C4-FD-28-A2-D2-57-AA-D3-B4-35-B5-14-04-EE |
network gives: |
D7-5A-34-5D-5D-20-7A-00-AA-D3-B4-35-B5-14-04-EE |
napier gives: |
12-B9-C5-4F-6F-E0-EC-80-AA-D3-B4-35-B5-14-04-EE |
Notice that the right-most element of the hash are always the same, if the password is less than eight characters. With more than eight characters we get:
networksims gives: |
D7-5A-34-5D-5D-20-7A-00-38-32-A0-DB-BA-51-68-07 |
napier123 gives: |
67-82-2A-34-ED-C7-48-92-B7-5E-0C-8D-76-95-4A-50 |
The LM hash is computed as (taken from Wikipedia):
- The user’s password is converted to uppercase.
- This password is null-padded to 14 bytes.
- The “fixed-length” password is split into two 7-byte halves.
- These values are used to create two DES keys, one from each 7-byte half, by
converting the seven bytes into a bit stream, and inserting a parity-bit after
every seven bits. This generates the 64 bits needed for the DES key.
- Each of these keys is used to DES-encrypt the constant ASCII string “KGS!@#$%”,
resulting in two 8-byte ciphertext values. The DES CipherMode should Set to ECB,
and PaddingMode should set to NONE.
- These two ciphertext values are concatenated to form a 16-byte value, which is
the LM hash.
The code is:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections;
using System.Security.Cryptography;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
public partial class _Default5 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button6_Click(object sender, EventArgs e)
{
TextBox2.Text = "";
string s1 = TextBox1.Text;
byte[] hash = LMHash.Compute(s1);
foreach (byte s in hash)
{
TextBox2.Text = BitConverter.ToString(hash);
}
}
}
// Based on SourceForge Code
// http://en.sourceforge.jp/projects/sfnet_csharplmhash/downloads/csharplmhash/1.1.0.0/CSharpLMHash1.1.0.0.zip/
public static class LMHash
{
public static byte[] ComputeHalf(byte[] Half)
{
if (Half.Length == 0)
return new byte[] { 0xAA, 0xD3, 0xB4, 0x35, 0xB5, 0x14, 0x04, 0xEE };
else if (Half.Length > 7)
throw new NotSupportedException("Password halves greater than 7 " +
"characters are not supported");
Array.Resize(ref Half, 7);
StringBuilder binaryString = new StringBuilder();
foreach (char c in Half)
{
string s = Convert.ToString(c, 2);
int padLen = 8 - s.Length;
binaryString.Append(new string('0', padLen) + s);
}
for (int y = 8; y > 0; y--)
binaryString.Insert(y * 7, '0');
string binary = binaryString.ToString();
byte[] key = new byte[8];
for (int y = 0; y < 8; y++)
key[y] = Convert.ToByte(binary.Substring(y * 8, 8), 2);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
des.Key = key;
des.IV = new byte[8];
using (MemoryStream stream = new MemoryStream())
{
using (CryptoStream cryptStream = new CryptoStream(stream,
des.CreateEncryptor(), CryptoStreamMode.Write))
using (StreamWriter writer = new StreamWriter(cryptStream))
writer.Write("KGS!@#$%");
byte[] b = stream.ToArray();
Array.Resize(ref b, 8);
return b;
}
}
public static byte[] Compute(string Password)
{
if (Password.Length > 14)
throw new NotSupportedException("Passwords greater than 14 " +
"characters are not supported");
byte[] passBytes = Encoding.ASCII.GetBytes(Password.ToUpper());
byte[][] passHalves = new byte[2][];
if (passBytes.Length > 7)
{
int len = passBytes.Length - 7;
passHalves[0] = new byte[7];
passHalves[1] = new byte[len];
Array.Copy(passBytes, passHalves[0], 7);
Array.Copy(passBytes, 7, passHalves[1], 0, len);
}
else
{
passHalves[0] = passBytes;
passHalves[1] = new byte[0];
}
for (int x = 0; x < 2; x++)
passHalves[x] = ComputeHalf(passHalves[x]);
byte[] hash = new byte[16];
Array.Copy(passHalves[0], hash, 8);
Array.Copy(passHalves[1], 0, hash, 8, 8);
return hash;
}
}
|