J’ai récemment commencé à apprendre le C #. J’ai essayé de générer un hachage NTLM dans cette langue mais je ne pouvais pas trouver une fonction pour le faire pour moi. En python 3.x, je voudrais importer hashlib
et le calculer avec hashlib.new("md4", "Hello, World!".encode("utf-16le"))
.
J’ai cherché dans l’Explorateur d’objects en C # mais je n’ai rien trouvé, le plus proche étant une classe d’authentification Windows NTLM. J’ai également cherché dans la documentation de Microsoft et trouvé des calculasortingces de hachage, mais uniquement pour sha1 et md5.
Existe-t-il un moyen de calculer un hachage NTLM en C #? Pouvez-vous s’il vous plaît me montrer un exemple de la façon de le faire, et je préférerais une méthode courte pour restr simple.
Merci.
Vous pouvez créer une extension pour les fournisseurs de cryptographie existants en utilisant Reflection pour appeler CNG pour MD4 (ce que Net devrait probablement faire ou rendre beaucoup plus facile):
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(ssortingng 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, ssortingng methodName, params object[] args) { var internalType = (pType is ssortingng 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, ssortingng propertyName) { var internalType = (pType is ssortingng 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
Une fois que vous avez fait cela, quelques extensions d'aide vous permettront de l'utiliser facilement (j'ai modifié ceci pour créer un singleton afin qu'il ne soit pas obligé de réfléchir / créer à chaque fois que vous l'utilisez):
static class Ext { public static HashAlgorithm MD4Singleton; static Ext() { MD4Singleton = System.Security.Cryptography.MD4.Create(); } public static byte[] MD4(this ssortingng s) { return MD4Singleton.ComputeHash(System.Text.Encoding.Unicode.GetBytes(s)); } public static ssortingng AsHexSsortingng(this byte[] bytes) { return Ssortingng.Join("", bytes.Select(h => h.ToSsortingng("X2"))); } }
Vous n’appelez maintenant que les méthodes d’extension sur des exemples de données:
void Main() { var input = "testing"; var hash = input.MD4(); var hashStr = hash.AsHexSsortingng(); Console.WriteLine(hashStr); }
Je pense que vous devez utiliser le BouncyCastle pour calculer le HASH, il existe un portage .net qui fonctionne assez bien.
et voici toute l’étape pour calculer le hachage NTLM: https://asecuritysite.com/encryption/lmhash
Le code peut être trouvé à la fin de l’article ici. Il utilise BC pour le MD4, car la plupart des implémentations de MD4 disposent d’un moyen d’avertir les clés faibles. NTLM ne comptabilise pas les clés faibles, vous devez donc pouvoir les utiliser si elles se présentent.
https://markgamache.blogspot.com/2013/01/ntlm-challenge-response-is-100-broken.html
Voici une solution générale pour appeler CNG pour tout ALG_ID
valide, en fonction de la réponse acceptée ci-dessus. Merci 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); }
Créez une instance avec algID = 0x8002
pour MD4.