1 | //#define INIT_A
|
2 | //#define INIT_B
|
3 | //#define INIT_C
|
4 | //#define INIT_D
|
5 | //#define SQRT_2
|
6 | //#define SQRT_3
|
7 | using System;
|
8 | using System.Text;
|
9 |
|
10 | namespace NTLM
|
11 | {
|
12 | internal class _NTLM
|
13 | {
|
14 | private const uint INIT_A = 0x67452301;
|
15 | private const uint INIT_B = 0xefcdab89;
|
16 | private const uint INIT_C = 0x98badcfe;
|
17 | private const uint INIT_D = 0x10325476;
|
18 | private const uint SQRT_2 = 0x5a827999;
|
19 | private const uint SQRT_3 = 0x6ed9eba1;
|
20 |
|
21 | //private static uint[] nt_buffer = new uint[16];
|
22 | //private static uint[] output = new uint[4];
|
23 | //private static char[] hex_format = new char[34];
|
24 | //public static string result = "";
|
25 | //private static string itoa16 = "0123456789abcdef";
|
26 | //***************************************************************
|
27 |
|
28 | //public static void NTLM(string key)
|
29 | public static string Crypt(string key)
|
30 | {
|
31 | //int i = 0;
|
32 | //int length = key.Length;
|
33 |
|
34 | //memset(nt_buffer, 0, 16 * 4);
|
35 | //for (int z = 0; z < nt_buffer.Length; z++)
|
36 | //{
|
37 | // nt_buffer[z] = 16*4;
|
38 | //}
|
39 |
|
40 | // The length of key need to be <= 27 (bytes)
|
41 | // oder 13 char in C#
|
42 | if (key.Length > 13)
|
43 | key = key.Substring(0, 13);
|
44 |
|
45 | //for (; i < length/2; i++)
|
46 | //{
|
47 | // nt_buffer[i] = Convert.ToUInt32(key[2*i] | (key[2*i + 1] << 16));
|
48 | //}
|
49 | //if (length%2 == 1)
|
50 | //{
|
51 | // nt_buffer[i] = Convert.ToUInt32(key[length - 1] | 0x800000);
|
52 | //}
|
53 | //else
|
54 | //{
|
55 | // nt_buffer[i] = 0x80;
|
56 | //}
|
57 | ////put the length
|
58 | //nt_buffer[14] = Convert.ToUInt32(length << 4);
|
59 |
|
60 | var nt_buffer = new uint[16];
|
61 |
|
62 | // strings in C# sind IMMER Unicode, d.h. 1 char sind immer 2 bytes!
|
63 | var i = 0;
|
64 | foreach (var item in key)
|
65 | {
|
66 | var bytes = BitConverter.GetBytes(item);
|
67 | nt_buffer[i] = (uint)(bytes[0] | (bytes[1] << 16));
|
68 | i++;
|
69 | }
|
70 | nt_buffer[i] = 0x80;
|
71 | nt_buffer[14] = Convert.ToUInt32(key.Length << 4);
|
72 | // evtl. ist die folgende Zeile richtig und die vorhergehende falsch??
|
73 | //nt_buffer[i+1] = Convert.ToUInt32(key.Length << 4);
|
74 |
|
75 | uint a = INIT_A;
|
76 | uint b = INIT_B;
|
77 | uint c = INIT_C;
|
78 | uint d = INIT_D;
|
79 |
|
80 | /* Round 1 */
|
81 | a += (d ^ (b & (c ^ d))) + nt_buffer[0]; a = (a << 3) | (a >> 29);
|
82 | d += (c ^ (a & (b ^ c))) + nt_buffer[1]; d = (d << 7) | (d >> 25);
|
83 | c += (b ^ (d & (a ^ b))) + nt_buffer[2]; c = (c << 11) | (c >> 21);
|
84 | b += (a ^ (c & (d ^ a))) + nt_buffer[3]; b = (b << 19) | (b >> 13);
|
85 |
|
86 | a += (d ^ (b & (c ^ d))) + nt_buffer[4]; a = (a << 3) | (a >> 29);
|
87 | d += (c ^ (a & (b ^ c))) + nt_buffer[5]; d = (d << 7) | (d >> 25);
|
88 | c += (b ^ (d & (a ^ b))) + nt_buffer[6]; c = (c << 11) | (c >> 21);
|
89 | b += (a ^ (c & (d ^ a))) + nt_buffer[7]; b = (b << 19) | (b >> 13);
|
90 |
|
91 | a += (d ^ (b & (c ^ d))) + nt_buffer[8]; a = (a << 3) | (a >> 29);
|
92 | d += (c ^ (a & (b ^ c))) + nt_buffer[9]; d = (d << 7) | (d >> 25);
|
93 | c += (b ^ (d & (a ^ b))) + nt_buffer[10]; c = (c << 11) | (c >> 21);
|
94 | b += (a ^ (c & (d ^ a))) + nt_buffer[11]; b = (b << 19) | (b >> 13);
|
95 |
|
96 | a += (d ^ (b & (c ^ d))) + nt_buffer[12]; a = (a << 3) | (a >> 29);
|
97 | d += (c ^ (a & (b ^ c))) + nt_buffer[13]; d = (d << 7) | (d >> 25);
|
98 | c += (b ^ (d & (a ^ b))) + nt_buffer[14]; c = (c << 11) | (c >> 21);
|
99 | b += (a ^ (c & (d ^ a))) + nt_buffer[15]; b = (b << 19) | (b >> 13);
|
100 |
|
101 | /* Round 2 */
|
102 | a += ((b & (c | d)) | (c & d)) + nt_buffer[0] + SQRT_2; a = (a << 3) | (a >> 29);
|
103 | d += ((a & (b | c)) | (b & c)) + nt_buffer[4] + SQRT_2; d = (d << 5) | (d >> 27);
|
104 | c += ((d & (a | b)) | (a & b)) + nt_buffer[8] + SQRT_2; c = (c << 9) | (c >> 23);
|
105 | b += ((c & (d | a)) | (d & a)) + nt_buffer[12] + SQRT_2; b = (b << 13) | (b >> 19);
|
106 |
|
107 | a += ((b & (c | d)) | (c & d)) + nt_buffer[1] + SQRT_2; a = (a << 3) | (a >> 29);
|
108 | d += ((a & (b | c)) | (b & c)) + nt_buffer[5] + SQRT_2; d = (d << 5) | (d >> 27);
|
109 | c += ((d & (a | b)) | (a & b)) + nt_buffer[9] + SQRT_2; c = (c << 9) | (c >> 23);
|
110 | b += ((c & (d | a)) | (d & a)) + nt_buffer[13] + SQRT_2; b = (b << 13) | (b >> 19);
|
111 |
|
112 | a += ((b & (c | d)) | (c & d)) + nt_buffer[2] + SQRT_2; a = (a << 3) | (a >> 29);
|
113 | d += ((a & (b | c)) | (b & c)) + nt_buffer[6] + SQRT_2; d = (d << 5) | (d >> 27);
|
114 | c += ((d & (a | b)) | (a & b)) + nt_buffer[10] + SQRT_2; c = (c << 9) | (c >> 23);
|
115 | b += ((c & (d | a)) | (d & a)) + nt_buffer[14] + SQRT_2; b = (b << 13) | (b >> 19);
|
116 |
|
117 | a += ((b & (c | d)) | (c & d)) + nt_buffer[3] + SQRT_2; a = (a << 3) | (a >> 29);
|
118 | d += ((a & (b | c)) | (b & c)) + nt_buffer[7] + SQRT_2; d = (d << 5) | (d >> 27);
|
119 | c += ((d & (a | b)) | (a & b)) + nt_buffer[11] + SQRT_2; c = (c << 9) | (c >> 23);
|
120 | b += ((c & (d | a)) | (d & a)) + nt_buffer[15] + SQRT_2; b = (b << 13) | (b >> 19);
|
121 |
|
122 | /* Round 3 */
|
123 | a += (d ^ c ^ b) + nt_buffer[0] + SQRT_3; a = (a << 3) | (a >> 29);
|
124 | d += (c ^ b ^ a) + nt_buffer[8] + SQRT_3; d = (d << 9) | (d >> 23);
|
125 | c += (b ^ a ^ d) + nt_buffer[4] + SQRT_3; c = (c << 11) | (c >> 21);
|
126 | b += (a ^ d ^ c) + nt_buffer[12] + SQRT_3; b = (b << 15) | (b >> 17);
|
127 |
|
128 | a += (d ^ c ^ b) + nt_buffer[2] + SQRT_3; a = (a << 3) | (a >> 29);
|
129 | d += (c ^ b ^ a) + nt_buffer[10] + SQRT_3; d = (d << 9) | (d >> 23);
|
130 | c += (b ^ a ^ d) + nt_buffer[6] + SQRT_3; c = (c << 11) | (c >> 21);
|
131 | b += (a ^ d ^ c) + nt_buffer[14] + SQRT_3; b = (b << 15) | (b >> 17);
|
132 |
|
133 | a += (d ^ c ^ b) + nt_buffer[1] + SQRT_3; a = (a << 3) | (a >> 29);
|
134 | d += (c ^ b ^ a) + nt_buffer[9] + SQRT_3; d = (d << 9) | (d >> 23);
|
135 | c += (b ^ a ^ d) + nt_buffer[5] + SQRT_3; c = (c << 11) | (c >> 21);
|
136 | b += (a ^ d ^ c) + nt_buffer[13] + SQRT_3; b = (b << 15) | (b >> 17);
|
137 |
|
138 | a += (d ^ c ^ b) + nt_buffer[3] + SQRT_3; a = (a << 3) | (a >> 29);
|
139 | d += (c ^ b ^ a) + nt_buffer[11] + SQRT_3; d = (d << 9) | (d >> 23);
|
140 | c += (b ^ a ^ d) + nt_buffer[7] + SQRT_3; c = (c << 11) | (c >> 21);
|
141 | b += (a ^ d ^ c) + nt_buffer[15] + SQRT_3; b = (b << 15) | (b >> 17);
|
142 |
|
143 | var output = new uint[4];
|
144 | output[0] = a + INIT_A;
|
145 | output[1] = b + INIT_B;
|
146 | output[2] = c + INIT_C;
|
147 | output[3] = d + INIT_D;
|
148 |
|
149 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
150 | // Convert the hash to hex (for being readable)
|
151 | //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
152 | //for (i = 0; i < 4; i++)
|
153 | //{
|
154 | // int j = 0;
|
155 | // uint n = output[i];
|
156 | // //iterate the bytes of the integer
|
157 | // for (; j < 4; j++)
|
158 | // {
|
159 | // uint convert = n%256;
|
160 | // hex_format[i*8 + j*2 + 1] = itoa16[Convert.ToInt16(convert%16)];
|
161 | // convert = convert/16;
|
162 | // hex_format[i*8 + j*2 + 0] = itoa16[Convert.ToInt16(convert%16)];
|
163 | // n = n/256;
|
164 | // }
|
165 | //}
|
166 | ////null terminate the string
|
167 | //hex_format[33] = "0".ToCharArray()[0];
|
168 | //foreach (char k in hex_format)
|
169 | //{
|
170 | // result += k.ToString();
|
171 | //}
|
172 | var buffer = new StringBuilder();
|
173 | foreach (var o in output)
|
174 | {
|
175 | buffer.Append(o.ToString("X8"));
|
176 | }
|
177 | return buffer.ToString();
|
178 | }
|
179 |
|
180 | //internal static partial class DefineConstants
|
181 | //{
|
182 | // public const int INIT_A = 0x67452301;
|
183 | // public const long INIT_B = 0xefcdab89;
|
184 | // public const long INIT_C = 0x98badcfe;
|
185 | // public const int INIT_D = 0x10325476;
|
186 | // public const int SQRT_2 = 0x5a827999;
|
187 | // public const int SQRT_3 = 0x6ed9eba1;
|
188 | //}
|
189 | }
|
190 | }
|