mirror of
https://github.com/MichaelGrafnetter/DSInternals
synced 2025-01-05 21:49:47 +00:00
NTLM Strong Hash generation
This commit is contained in:
parent
02b3066b5f
commit
6cfe1c16a5
@ -70,5 +70,18 @@ namespace DSInternals.Common.Cryptography.Test
|
||||
string expected = "92937945B518814341DE3F726500D4FF";
|
||||
Assert.AreEqual(expected, result);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void NTHash_GenerateRandom()
|
||||
{
|
||||
byte[] randomHash1 = NTHash.GetRandom();
|
||||
byte[] randomHash2 = NTHash.GetRandom();
|
||||
|
||||
// Check hash size
|
||||
Assert.AreEqual(NTHash.HashSize, randomHash1.Length);
|
||||
|
||||
// Check that the hashes are not the same
|
||||
Assert.AreNotEqual(randomHash1.ToHex(), randomHash2.ToHex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
{
|
||||
using DSInternals.Common.Interop;
|
||||
using System.Security;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
// See http://msdn.microsoft.com/en-us/library/system.security.cryptography.hashalgorithm%28v=vs.110%29.aspx
|
||||
public static class NTHash
|
||||
@ -45,5 +46,15 @@
|
||||
Validator.AssertSuccess(result);
|
||||
return hash;
|
||||
}
|
||||
|
||||
public static byte[] GetRandom()
|
||||
{
|
||||
using (var rng = RandomNumberGenerator.Create())
|
||||
{
|
||||
var randomHash = new byte[HashSize];
|
||||
rng.GetBytes(randomHash);
|
||||
return randomHash;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,27 +10,27 @@
|
||||
/// </summary>
|
||||
/// <remarks>This structure is undocumented. Kudos to Benjamin Delpy for figuring out the most important parts of it.</remarks>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
internal struct KerberosCryptoSystem
|
||||
internal class KerberosCryptoSystem
|
||||
{
|
||||
internal KerberosKeyType Type;
|
||||
int BlockSize;
|
||||
KerberosKeyType Type1;
|
||||
internal int KeySize;
|
||||
int Size;
|
||||
int Unknown2;
|
||||
int Unknown3;
|
||||
internal readonly KerberosKeyType Type;
|
||||
readonly int BlockSize;
|
||||
readonly KerberosKeyType Type1;
|
||||
internal readonly int KeySize;
|
||||
readonly int Size;
|
||||
readonly int Unknown2;
|
||||
readonly int Unknown3;
|
||||
[MarshalAs(UnmanagedType.LPWStr)]
|
||||
internal string AlgorithmName;
|
||||
IntPtr Initialize;
|
||||
IntPtr Encrypt;
|
||||
IntPtr Decrypt;
|
||||
IntPtr Finish;
|
||||
private KerberosKeyDerivationFunction KeyDerivationFunction;
|
||||
IntPtr RandomKey;
|
||||
IntPtr Control;
|
||||
IntPtr Unknown4;
|
||||
IntPtr Unknown5;
|
||||
IntPtr Unknown6;
|
||||
internal readonly string AlgorithmName;
|
||||
readonly IntPtr Initialize;
|
||||
readonly IntPtr Encrypt;
|
||||
readonly IntPtr Decrypt;
|
||||
readonly IntPtr Finish;
|
||||
readonly KerberosKeyDerivationFunction KeyDerivationFunction;
|
||||
readonly IntPtr RandomKey;
|
||||
readonly IntPtr Control;
|
||||
readonly IntPtr Unknown4;
|
||||
readonly IntPtr Unknown5;
|
||||
readonly IntPtr Unknown6;
|
||||
|
||||
delegate NtStatus KerberosKeyDerivationFunction([In] ref SecureUnicodeString password, [In] ref UnicodeString salt, int iterations, [MarshalAs(UnmanagedType.LPArray), In, Out] byte[] key);
|
||||
|
||||
|
@ -14,7 +14,6 @@ namespace DSInternals.Common.Interop
|
||||
internal const int LMHashNumBits = 128;
|
||||
internal const int LMHashNumBytes = NTHashNumBits / 8;
|
||||
internal const int LMPasswordMaxChars = 14;
|
||||
// TODO: Validate NT Hash max chars
|
||||
internal const int NTPasswordMaxChars = 127;
|
||||
|
||||
private const int MaxRegistryKeyClassSize = 256;
|
||||
@ -198,25 +197,7 @@ namespace DSInternals.Common.Interop
|
||||
}
|
||||
|
||||
[DllImport(CryptDll, CharSet = CharSet.Auto, SetLastError = true)]
|
||||
private static extern NtStatus CDLocateCSystem(KerberosKeyType type, out IntPtr cryptoSystem);
|
||||
|
||||
internal static NtStatus CDLocateCSystem(KerberosKeyType type, out KerberosCryptoSystem cryptoSystem)
|
||||
{
|
||||
IntPtr cryptoSystemPtr;
|
||||
NtStatus status = CDLocateCSystem(type, out cryptoSystemPtr);
|
||||
|
||||
if(status == NtStatus.Success)
|
||||
{
|
||||
cryptoSystem = (KerberosCryptoSystem)Marshal.PtrToStructure(cryptoSystemPtr, typeof(KerberosCryptoSystem));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Return a blank structure
|
||||
cryptoSystem = new KerberosCryptoSystem();
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
internal static extern NtStatus CDLocateCSystem(KerberosKeyType type, out KerberosCryptoSystem cryptoSystem);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a subkey under HKEY_USERS or HKEY_LOCAL_MACHINE and loads the data from the specified registry hive into that subkey.
|
||||
|
Loading…
Reference in New Issue
Block a user