2017-10-18 21 views
3

私は最近、C#の学習を始めました。私はこの言語でNTLMハッシュを生成しようとしましたが、私のためにこれを行う関数を見つけることができませんでした。 python 3.xではhashlibをインポートし、hashlib.new("md4", "Hello, World!".encode("utf-16le"))で計算します。C#NTLMハッシュ計算機

C#のオブジェクトブラウザで検索しましたが、何も見つかりませんでした。最も近いのはWindows NTLM認証クラスでした。私もMicrosoftのドキュメントを検索し、ハッシュ計算機を見つけましたが、sha1とmd5のみでした。

C#でNTLMハッシュを計算する方法はありますか?私にそれを行う方法の例を教えてもらえますか?それを簡単に保つための短い方法を好むでしょう。

ありがとうございました。

答えて

2

あなたはMD4のための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<T>(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<T>(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<SafeHandle>(null, UtilsType, "CreateHash", GetInternalPropertyValueOfInternalType<object>(null, UtilsType, "StaticProvHandle"), algid); 
      } 

      internal static void HashData(SafeHandle h, byte[] data, int ibStart, int cbSize) { 
       InvokeInternalMethodOfType<object>(null, UtilsType, "HashData", h, data, ibStart, cbSize); 
      } 

      internal static byte[] EndHash(SafeHandle h) { 
       return InvokeInternalMethodOfType<byte[]>(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); 
     } 
    } 
} 

あなたはヘルパー拡張子のカップルは、それが/反映の作業を行う必要はありませんので、(私はシングルトンを作成するには、これを変更し、あなたが簡単にそれを使用できるようになる、ということをやった後はあなたがそれを使用するたびに作成する):

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); 
} 
+0

NTLMハッシュは、ASCIIではなくUTF-16LEを使用します。 ( 'Encoding.Unicode'はUTF-16LEの組み込みインスタンスです。) –

+0

素敵なキャッチ - ありがとう! – NetMage

+0

オンラインで作成したハッシュを確認しました。 –

1

あなたは、HASHを計算するにはBouncyCastleを使用する必要があると思います。かなりうまく動作する.net移植があります。

、ここでNTLMハッシュを計算するために、すべてのステップです: https://asecuritysite.com/encryption/lmhash

1

コードはここに記事の最後に見つけることができます。たいていのMD4の実装では弱い鍵を手に入れる方法があるので、MD4にはBCが使用されています。 NTLMは弱いキーを考慮しないので、発生した場合には使用する必要があります。

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

+0

私は120 000語の辞書をテストし、両方のメソッドが同じハッシュを作成しましたが、BCバージョンは約2倍高速です。 (0.9秒対1.8秒) –