C#NTLM哈希计算器

我最近开始学习C#。 我尝试用这种语言生成一个NTLM哈希,但我找不到一个函数来为我做这个。 在python 3.x中,我将导入hashlib并使用hashlib.new("md4", "Hello, World!".encode("utf-16le"))计算它hashlib.new("md4", "Hello, World!".encode("utf-16le"))

我在C#中搜索对象浏览器但没有找到任何内容,最接近的是Windows NTLM身份validation类。 我还搜索了微软的文档并发现了哈希计算器,但仅适用于sha1和md5。

有没有办法在C#中计算NTLM哈希? 你能告诉我一个如何做的例子,我宁愿用一个简短的方法来保持简单。

谢谢。

您可以使用Reflection为CN4调用CNG来创建对现有加密提供程序的扩展(某些.Net可能应该这样做,或者更容易):

 namespace System.Security.Cryptography { [System.Runtime.InteropServices.ComVisible(true)] public abstract class MD4 : HashAlgorithm { static MD4() { CryptoConfig.AddAlgorithm(typeof(MD4CryptoServiceProvider), "System.Security.Cryptography.MD4"); } protected MD4() { HashSizeValue = 128; } new static public MD4 Create() { return Create("System.Security.Cryptography.MD4"); } new static public MD4 Create(string algName) { return (MD4)CryptoConfig.CreateFromName(algName); } } [System.Runtime.InteropServices.ComVisible(true)] public sealed class MD4CryptoServiceProvider : MD4 { internal static class Utils { internal static Type UtilsType = Type.GetType("System.Security.Cryptography.Utils"); public static T InvokeInternalMethodOfType(object o, object pType, string methodName, params object[] args) { var internalType = (pType is string internalTypeName) ? Type.GetType(internalTypeName) : (Type)pType; var internalMethods = internalType.GetMethods(BindingFlags.NonPublic | BindingFlags.FlattenHierarchy | (o == null ? BindingFlags.Static : 0)); var internalMethod = internalMethods.Where(m => m.Name == methodName && m.GetParameters().Length == args.Length).Single(); return (T)internalMethod?.Invoke(o, args); } public static T GetInternalPropertyValueOfInternalType(object o, object pType, string propertyName) { var internalType = (pType is string internalTypeName) ? Type.GetType(internalTypeName) : (Type)pType; var internalProperty = internalType.GetProperty(propertyName, BindingFlags.NonPublic | (o == null ? BindingFlags.Static : 0)); return (T)internalProperty.GetValue(o); } internal static SafeHandle CreateHash(int algid) { return InvokeInternalMethodOfType(null, UtilsType, "CreateHash", GetInternalPropertyValueOfInternalType(null, UtilsType, "StaticProvHandle"), algid); } internal static void HashData(SafeHandle h, byte[] data, int ibStart, int cbSize) { InvokeInternalMethodOfType(null, UtilsType, "HashData", h, data, ibStart, cbSize); } internal static byte[] EndHash(SafeHandle h) { return InvokeInternalMethodOfType(null, UtilsType, "EndHash", h); } } internal const int ALG_CLASS_HASH = (4 << 13); internal const int ALG_TYPE_ANY = (0); internal const int ALG_SID_MD4 = 2; internal const int CALG_MD4 = (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_MD4); [System.Security.SecurityCritical] private SafeHandle _safeHashHandle = null; [System.Security.SecuritySafeCritical] public MD4CryptoServiceProvider() { if (CryptoConfig.AllowOnlyFipsAlgorithms) throw new InvalidOperationException("Cryptography_NonCompliantFIPSAlgorithm"); Contract.EndContractBlock(); // cheat with Reflection _safeHashHandle = Utils.CreateHash(CALG_MD4); } protected override void Dispose(bool disposing) { if (_safeHashHandle != null && !_safeHashHandle.IsClosed) _safeHashHandle.Dispose(); base.Dispose(disposing); } public override void Initialize() { if (_safeHashHandle != null && !_safeHashHandle.IsClosed) _safeHashHandle.Dispose(); _safeHashHandle = Utils.CreateHash(CALG_MD4); } protected override void HashCore(byte[] rgb, int ibStart, int cbSize) { Utils.HashData(_safeHashHandle, rgb, ibStart, cbSize); } protected override byte[] HashFinal() { return Utils.EndHash(_safeHashHandle); } } } 

一旦你完成了这个,一些帮助扩展将让你轻松使用它(我修改了它来创建一个单例,所以它不必每次使用时都做reflection/创建的工作):

 static class Ext { public static HashAlgorithm MD4Singleton; static Ext() { MD4Singleton = System.Security.Cryptography.MD4.Create(); } public static byte[] MD4(this string s) { return MD4Singleton.ComputeHash(System.Text.Encoding.Unicode.GetBytes(s)); } public static string AsHexString(this byte[] bytes) { return String.Join("", bytes.Select(h => h.ToString("X2"))); } } 

现在,您只需在某些示例数据上调用扩展方法:

 void Main() { var input = "testing"; var hash = input.MD4(); var hashStr = hash.AsHexString(); Console.WriteLine(hashStr); } 

我认为你需要使用BouncyCastle来计算HASH,有一个非常好的.net移植。

以下是计算NTLM哈希的所有步骤: https : //asecuritysite.com/encryption/lmhash

代码可以在post的末尾找到。 它使用BC作为MD4,因为大多数MD4实现都有一种方法可以使用弱键。 NTLM不会考虑弱密钥,因此如果出现密钥,您必须能够使用它们。

https://markgamache.blogspot.com/2013/01/ntlm-challenge-response-is-100-broken.html

根据上面接受的答案,这是为CNG调用任何有效ALG_ID的一般解决方案。 谢谢NetMage!

 public class HashByID : HashAlgorithm { static readonly Dictionary hashSizes = new Dictionary() { {0x8001,128},{0x8002,128},{0x8003,128},{0x8004,160},{0x8006,128},{0x8007,160},{0x800c,256},{0x800d,384},{0x800e,512}}; static readonly Type hUtils; static readonly SafeHandle hStaticProv; static readonly Func fCreate; static readonly Action fHash; static readonly Func fHashEnd; public static bool inited; public readonly int algID; SafeHandle hh = null; static HashByID() { try { hUtils = Type.GetType("System.Security.Cryptography.Utils"); hStaticProv = (SafeHandle)hUtils.GetProperty("StaticProvHandle", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null, null); fCreate = (Func)hUtils.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(x => x.Name == "CreateHash" && x.GetParameters().Length == 2).Single().CreateDelegate(null, typeof(SafeHandle), typeof(int), typeof(SafeHandle)); fHash = (Action)hUtils.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(x => x.Name == "HashData" && x.GetParameters().Length == 4).Single().CreateDelegate(null, typeof(SafeHandle), typeof(byte[]), typeof(int), typeof(int)); fHashEnd = (Func)hUtils.GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(x => x.Name == "EndHash" && x.GetParameters().Length == 1).Single().CreateDelegate(null, typeof(SafeHandle), typeof(byte[])); inited = true; } catch { } } public HashByID(int algID) { if (algID == 0x8009) algID = 0x8004; //map CALG_HMAC -> CALG_SHA1 this.algID = algID; hashSizes.TryGetValue(algID, out HashSizeValue); Initialize(); } protected override void Dispose(bool disposing) { if (hh != null && !hh.IsClosed) hh.Dispose(); base.Dispose(disposing); } public override void Initialize() { if (hh != null && !hh.IsClosed) hh.Dispose(); hh = fCreate(hStaticProv, algID); } protected override void HashCore(byte[] data, int ofs, int len) { fHash(hh, data, ofs, len); } protected override byte[] HashFinal() { return fHashEnd(hh); } } //Delegate creation helper public static Delegate CreateDelegate(this MethodInfo methodInfo, object target, params Type[] custTypes) { Func getType; bool isAction = methodInfo.ReturnType.Equals((typeof(void))), cust = custTypes.Length > 0; Type[] types = cust ? custTypes : methodInfo.GetParameters().Select(p => p.ParameterType).ToArray(); if (isAction) getType = Expression.GetActionType; else { getType = Expression.GetFuncType; if (!cust) types = types.Concat(new[] { methodInfo.ReturnType }).ToArray(); } if (cust) { int i, nargs = types.Length - (isAction ? 0 : 1); var dm = new DynamicMethod(methodInfo.Name, isAction ? typeof(void) : types.Last(), types.Take(nargs).ToArray(), typeof(object), true); var il = dm.GetILGenerator(); for (i = 0; i < nargs; i++) il.Emit(OpCodes.Ldarg_S, i); il.Emit(OpCodes.Call, methodInfo); il.Emit(OpCodes.Ret); if (methodInfo.IsStatic) return dm.CreateDelegate(getType(types)); return dm.CreateDelegate(getType(types), target); } if (methodInfo.IsStatic) return Delegate.CreateDelegate(getType(types), methodInfo); return Delegate.CreateDelegate(getType(types), target, methodInfo.Name); } 

为MD4创建一个algID = 0x8002的实例。