3

有効なコンテキストで win32 API から EncryptMessage (SChannel) を使用する場合、正しい順序で 4 つのバッファーを提供しています。ドキュメントによると、No SECBUFFER_DATA type buffer was found. 速度のために pvBuffers のセットを連続したメモリから割り当てる必要があることはわかっていますが、簡単にするために何が何であるかを明確にしました。誰が問題が何であるかを見ることができますか?

ありがとう、ブルース

コードは次のとおりです。

procedure TTCPSocket.SSPEncryptBuffer(SSPCtx: PCtxtHandle; InData: PAnsiChar; InDataLength: Cardinal);
var
  SecStatus: TSecurityStatus;

  SecBufDesc: TSecBufferDesc;
  SecBufs: packed array [0 .. 3] of TSecBuffer;
begin
  SecBufs[0].BufferType := SECBUFFER_STREAM_HEADER;
  SecBufs[0].cbBuffer := FSecPkgSizes.cbHeader;
  SecBufs[0].pvBuffer := AllocMem(FSecPkgSizes.cbHeader); 

  SecBufs[1].BufferType := SECBUFFER_DATA;
  SecBufs[1].cbBuffer := InDataLength; 
  SecBufs[1].pvBuffer := InData; 

  SecBufs[2].BufferType := SECBUFFER_STREAM_TRAILER;
  SecBufs[2].cbBuffer := FSecPkgSizes.cbTrailer;
  SecBufs[2].pvBuffer := AllocMem(FSecPkgSizes.cbTrailer);

  SecBufs[3].BufferType := SECBUFFER_EMPTY;
  SecBufs[3].cbBuffer := 0;
  SecBufs[3].pvBuffer := nil;

  SecBufDesc.ulVersion := SECBUFFER_VERSION;
  SecBufDesc.cBuffers := 4;
  SecBufDesc.pBuffers := @SecBufs[0];

  SecStatus := EncryptMessage(SSPCtx, 0, @SecBufDesc, 0);

  if SecStatus <> SEC_E_OK then
  begin
    // Error code..
  end;
end;

実行可能ファイルに挿入された STRACE を使用しましたが、この行は興味深いようです。

12/07/2009 23:10:30:635 - SecBuffer #0 BufferType:0x00000007 cbBuffer:5
12/07/2009 23:10:30:636 - SecBuffer #1 BufferType:0x00000001 cbBuffer:13
12/07/2009 23:10:30:636 - SECBUFFER_DATA - 13 byte(s) / EncryptMessage - INPUT 
=====================================================
      00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f   0123456789abcdef

0000: 68 65 6c 6c 6f 20 77 6f 72 6c 64 21 00            hello world!.
=====================================================
12/07/2009 23:10:30:636 - SecBuffer #2 BufferType:0x00000006 cbBuffer:36
12/07/2009 23:10:30:636 - SecBuffer #3 BufferType:0x00000000 cbBuffer:0
12/07/2009 23:10:30:636 - 

 *** WARNING : EncryptMessage failed (80090308) ***

OSが正しい情報を取得しているように見えます。

少し検索したところ、80090308 は通常、サーバーの完全な名前が件名に含まれている必要があるという点で、証明書に問題があることを意味することがわかりました CN=www.foobar.com しかし、これでも問題は解決しませんでした。証明書とCA は OpenSSL で生成されます。

4

2 に答える 2

3

これは、Windows で非対称暗号を使用して何かをしようとしたときに人々が遭遇する一般的な問題のように思われるため、ここでは多少の推測があります。

自己署名 CA であり、証明書が自己署名 CA で署名されている場合は、その CA をコンピューターの信頼できる CA ストアにインポートする必要があります。

これを行うには、MMC を実行し、次の手順を実行します。

  1. ファイル -> スナップインの追加と削除

  2. コンピューター上のすべてのユーザーに適用する場合は、[証明書] スナップインを追加し、[コンピューター アカウント] を選択します。

  3. 「信頼されたルート証明機関 -> 証明書」ツリー ノードを開きます。

  4. 「証明書」を右クリックし、インポートを選択します。

  5. CA 証明書ファイルをインポートします。(問題なく PEM エンコードされたバージョンを受け入れる必要があります。)

ほとんどの場合、CN はマシン証明書のマシン名と一致する必要がありますが、CA が Windows 信頼ストレージにインポートされていない場合、CA の検証は失敗します。

お役に立てば幸いです。

于 2009-12-12T16:06:16.423 に答える
2

を使用してクライアントとサーバーの両方でコンテキストを設定する場合。

InitializeSecurityContext // Schannel Client
AcceptSecurityContext // Schannel Server

EncryptMessage と DecryptMessage の両方に必要な SecBuffer のタイプを決定するため、必要なコンテキストのタイプに渡すフラグには特に注意してください。たとえば、私は現在使用しています。

  FClientContextFlags :=
    ISC_REQ_CONFIDENTIALITY or
    ISC_REQ_STREAM or
    ISC_REQ_ALLOCATE_MEMORY;

  FServerContextFlags :=
    ASC_REQ_CONFIDENTIALITY or
    ASC_REQ_STREAM or
    ASC_REQ_ALLOCATE_MEMORY;

つまり、EncryptMessage には 4 つの SecBuffers が必要です。

SECBUFFER_STREAM_HEADER
SECBUFFER_DATA
SECBUFFER_STREAM_TRAILER
SECBUFFER_EMPTY

DecryptMessage の場合、4 つの SecBuffers も必要です。

SECBUFFER_DATA
SECBUFFER_EMPTY
SECBUFFER_EMPTY
SECBUFFER_EMPTY

私の問題は、 *_REQ_STREAM と *_REQ_CONNECTION があり、ドキュメントをよく読むと本質的に互換性がないことでした。これは、有効な証明書/信頼できるものなどがあることを確認することに加えて.

これが誰かに役立つことを願っています。

ブルース

于 2009-12-16T04:04:59.540 に答える