3

.NETでのマウスの動きとキーストロークからエントロピーを生成することに興味があります(暗号化の目的で、これは、マウスの動きとキーストロークデータがアプリケーション自体のイベントを介して受信されるFormsアプリケーション、またはマウスの動きとキーストロークのデータはJavaScriptを使用して記録され、Ajaxを介してサーバーに送信されます。

この手法は現在、新しいMEGAサイトで採用されています。

私は自分で少し調べて、C ++の良い例のように見えるものに出くわしましたが、それは私のC /C++の知識から少し外れています。

http://etutorials.org/Programming/secure+programming/Chapter+11.+Random+Numbers/11.21+Gathering+Entropy+from+Mouse+Events+on+Windows/

    #include <windows.h>
    #include <wincrypt.h>
    #include <commctrl.h>

    #define SPC_ENTROPY_PER_SAMPLE  0.5
    #define SPC_MOUSE_DLGID         102
    #define SPC_PROGRESS_BARID      1000
    #define SPC_MOUSE_COLLECTID     1003
    #define SPC_MOUSE_STATIC        1002

    typedef struct {
      double     dEntropy;
      DWORD      cbRequested;
      POINT      ptLastPos;
      DWORD      dwLastTime;
      HCRYPTHASH hHash;
    } SPC_DIALOGDATA;

    typedef struct {
      POINT ptMousePos;
      DWORD dwTickCount;
    } SPC_MOUSEPOS;

    static BOOL CALLBACK MouseEntropyProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,
                                          LPARAM lParam) {
      SPC_MOUSEPOS    MousePos;
      SPC_DIALOGDATA  *pDlgData;

      switch (uMsg) {
        case WM_INITDIALOG:
          pDlgData = (SPC_DIALOGDATA *)lParam;
          SetWindowLong(hwndDlg, DWL_USER, lParam);
          SendDlgItemMessage(hwndDlg, SPC_PROGRESS_BARID, PBM_SETRANGE32, 0,
                             pDlgData->cbRequested);
          return TRUE;

        case WM_COMMAND:
          if (LOWORD(wParam) =  = IDOK && HIWORD(wParam) =  = BN_CLICKED) {
            EndDialog(hwndDlg, TRUE);
            return TRUE;
          }
          break;

        case WM_MOUSEMOVE:
          pDlgData = (SPC_DIALOGDATA *)GetWindowLong(hwndDlg, DWL_USER);
          if (pDlgData->dEntropy < pDlgData->cbRequested) {
            MousePos.ptMousePos.x = LOWORD(lParam);
            MousePos.ptMousePos.y = HIWORD(lParam);
            MousePos.dwTickCount  = GetTickCount(  );
            ClientToScreen(hwndDlg, &(MousePos.ptMousePos));
            CryptHashData(pDlgData->hHash, (BYTE *)&MousePos, sizeof(MousePos), 0);
            if ((MousePos.ptMousePos.x != pDlgData->ptLastPos.x ||
                 MousePos.ptMousePos.y != pDlgData->ptLastPos.y)  && 
                MousePos.dwTickCount - pDlgData->dwLastTime > 100) {
              pDlgData->ptLastPos = MousePos.ptMousePos;
              pDlgData->dwLastTime = MousePos.dwTickCount;
              pDlgData->dEntropy += SPC_ENTROPY_PER_SAMPLE;
              SendDlgItemMessage(hwndDlg, SPC_PROGRESS_BARID, PBM_SETPOS,
                                 (WPARAM)pDlgData->dEntropy, 0);
              if (pDlgData->dEntropy >= pDlgData->cbRequested) {
                EnableWindow(GetDlgItem(hwndDlg, IDOK), TRUE);
                SetFocus(GetDlgItem(hwndDlg, IDOK));
                MessageBeep(0xFFFFFFFF);
              }
            }
          }
          return TRUE;
      }

      return FALSE;
    }

    BOOL SpcGatherMouseEntropy(HINSTANCE hInstance, HWND hWndParent, 
                                  BYTE *pbOutput, DWORD cbOutput) {
      BOOL           bResult = FALSE;
      BYTE           *pbHashData = 0;
      DWORD          cbHashData, dwByteCount = sizeof(DWORD);
      HCRYPTHASH     hHash = 0;
      HCRYPTPROV     hProvider = 0;
      SPC_DIALOGDATA DialogData;

      if (!CryptAcquireContext(&hProvider, 0, MS_DEF_PROV, PROV_RSA_FULL,
                              CRYPT_VERIFYCONTEXT)) goto done;
      if (!CryptCreateHash(hProvider, CALG_SHA1, 0, 0, &hHash)) goto done;
      if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&cbHashData, &dwByteCount,
                             0)) goto done;
      if (cbOutput > cbHashData) goto done;
      if (!(pbHashData = (BYTE *)LocalAlloc(LMEM_FIXED, cbHashData))) goto done;

      DialogData.dEntropy     = 0.0;
      DialogData.cbRequested = cbOutput * 8;
      DialogData.hHash        = hHash;
      DialogData.dwLastTime   = 0;
      GetCursorPos(&(DialogData.ptLastPos));

      bResult = DialogBoxParam(hInstance, MAKEINTRESOURCE(SPC_MOUSE_DLGID),
                               hWndParent, MouseEntropyProc, (LPARAM)&DialogData);

      if (bResult) {
        if (!CryptGetHashParam(hHash, HP_HASHVAL, pbHashData, &cbHashData, 0))
          bResult = FALSE;
        else
          CopyMemory(pbOutput, pbHashData, cbOutput);
      }

    done:
      if (pbHashData) LocalFree(pbHashData);
      if (hHash) CryptDestroyHash(hHash);
      if (hProvider) CryptReleaseContext(hProvider, 0);
      return bResult;
    }
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine,
                   int nShowCmd) {
  BYTE                 pbEntropy[20];
  INITCOMMONCONTROLSEX CommonControls;

  CommonControls.dwSize = sizeof(CommonControls);
  CommonControls.dwICC  = ICC_PROGRESS_CLASS;
  InitCommonControlsEx(&CommonControls);
  SpcGatherMouseEntropy(hInstance, 0, pbEntropy, sizeof(pbEntropy));
  return 0;
}

誰かが.NET(C#またはVB.Netで問題ありません)を介してこれを達成する方法に光を当てることができれば、最も役に立ちます。

前もって感謝します。

クリス

4

1 に答える 1

3

あなたはそれをする必要はありません、マイクロソフトはあなたのためにすでにそれをしました。組み込みの.NETメソッドRNGCryptoServiceProvider.GetBytes()は、WindowsCryptGenRandomから派生した高品質の真のランダムバイトを提供します。RFC 4086を引用するには:

Windows CryptAPI暗号化サービスプロバイダーは、すべてのユーザーのシード状態変数を格納します。CryptGenRandomが呼び出されると、これは、呼び出しで提供されるランダム性、およびプロセスID、スレッドID、システムクロック、システム時間、システムカウンター、メモリステータス、空きディスククラスター、ハッシュされたユーザーなどのさまざまなシステムおよびユーザーデータと組み合わされます。環境ブロック。このデータはすべてSHA-1に送られ、出力はRC4キーストリームのシードに使用されます。そのキーストリームは、要求された疑似ランダムデータを生成し、ユーザーのシード状態変数を更新するために使用されます。

Windows ".NET"のユーザーは、おそらくRNGCryptoServiceProvider.GetBytesメソッドインターフェイスを使用する方が簡単だと思うでしょう。

車輪を再発明する必要はありません、それはあなたのためにすでに構築されています。

于 2013-01-21T00:00:09.413 に答える