次の方法で共有


DecryptMessage (Schannel) 関数

DecryptMessage (Schannel) 関数は、メッセージの暗号化を解除します。 一部のパッケージでは、メッセージを暗号化および暗号化解除するのではなく、整合性ハッシュを実行してチェックします。

この関数は、Schannel セキュリティ サポート プロバイダー (SSP) と共に使用して、接続属性の再ネゴシエーション (やり直し) または接続のシャットダウンのために、メッセージ送信者からの要求を通知します。

注意

EncryptMessage (Schannel)DecryptMessage (Schannel) を 1 つの セキュリティ サポート プロバイダー インターフェイス (SSPI) コンテキストで 2 つの異なるスレッドから同時に呼び出すことができます (1 つのスレッドが暗号化されていて、もう一方が暗号化解除している場合)。 複数のスレッドが暗号化されている場合、または複数のスレッドが暗号化を解除している場合、各スレッドは一意のコンテキストを取得する必要があります。

構文

SECURITY_STATUS SEC_Entry DecryptMessage(
  _In_    PCtxtHandle    phContext,
  _Inout_ PSecBufferDesc pMessage,
  _In_    ULONG          MessageSeqNo,
  _Out_   PULONG         pfQOP
);

パラメーター

phContext [in]

メッセージの暗号化を解除するために使用される セキュリティ コンテキスト へのハンドル。

pMessage [in, out]

SecBufferDesc 構造体へのポインター。 入力時に、構造体は 1 つ以上 の SecBuffer 構造体を 参照します。 これらのうちの 1 つは、SECBUFFER_DATA型である場合があります。 そのバッファーには、暗号化されたメッセージが含まれています。 暗号化されたメッセージは暗号化解除され、バッファーの元の内容が上書きされます。

接続指向ではないコンテキストで Schannel SSP を使用する場合は、入力時に、構造体に 4 つの SecBuffer 構造体が含まれている必要があります。 1 つのバッファーがSECBUFFER_DATA型であり、暗号化されたメッセージが含まれている必要があります。このバッファーには暗号化が解除されます。 残りのバッファーは出力に使用され、SECBUFFER_EMPTY型である必要があります。 接続指向コンテキストの場合は、非接続指向コンテキストで説明されているように、SECBUFFER_DATA型バッファーを指定する必要があります。 さらに、セキュリティ トークンを含む 2 つ目のSECBUFFER_TOKEN型バッファーも指定する必要があります。

MessageSeqNo [in]

トランスポート アプリケーションで予期されるシーケンス番号 (存在する場合)。 トランスポート アプリケーションでシーケンス番号が保持されない場合は、このパラメーターを 0 に設定する必要があります。

Schannel SSP を使用する場合は、このパラメーターを 0 に設定する必要があります。 Schannel SSP はシーケンス番号を使用しません。

pfQOP [out]

保護の品質を示すパッケージ固有のフラグを受け取る ULONG 型の変数へのポインター。

Schannel SSP を使用する場合、このパラメーターは使用されず、 NULL に設定する必要があります。

このパラメーターには、次のフラグを指定できます。

説明
SECQOP_WRAP_NO_ENCRYPT
メッセージは暗号化されませんでしたが、ヘッダーまたはトレーラーが生成されました。
メモ: KERB_WRAP_NO_ENCRYPTには、同じ値と同じ意味があります。

戻り値

関数がメッセージが正しいシーケンスで受信されたことを確認すると、関数は SEC_E_OKを返します。

関数がメッセージの暗号化解除に失敗すると、次のいずれかのエラー コードが返されます。

リターン コード 説明
SEC_E_INVALID_HANDLE 無効なコンテキスト ハンドルが phContext パラメーターで指定されました。 Schannel SSP と共に使用されます。
SEC_E_INVALID_TOKEN バッファーの型が正しくないか、SECBUFFER_DATA型のバッファーが見つかりませんでした。 Schannel SSP と共に使用されます。
SEC_E_MESSAGE_ALTERED メッセージが変更されました。 Schannel SSP と共に使用されます。
SEC_E_OUT_OF_SEQUENCE メッセージが正しい順序で受信されませんでした。
SEC_I_CONTEXT_EXPIRED メッセージ送信者は接続の使用を終了し、シャットダウンを開始しました。 シャットダウンの開始または認識の詳細については、「 Schannel 接続のシャットダウン」を参照してください。 Schannel SSP と共に使用されます。
SEC_I_RENEGOTIATE リモート パーティには新しいハンドシェイク シーケンスが必要です。または、アプリケーションがシャットダウンを開始したばかりです。 ネゴシエーション ループに戻り、 AcceptSecurityContext (Schannel) または InitializeSecurityContext (Schannel) を呼び出し、DecryptMessage() から返されるSECBUFFER_EXTRAを渡します。

解説

アプリケーションがリモート パーティからデータを読み取り、 DecryptMessage (Schannel) を使用して復号化を試み、 DecryptMessage (Schannel) が成功したが出力バッファーが空であることを検出することがあります。 これは通常の動作であり、アプリケーションはそれに対処できる必要があります。

Schannel SSP を使用すると、メッセージ送信者が接続をシャットダウンしたときに DecryptMessage (General) 関数はSEC_I_CONTEXT_EXPIREDを返します。 シャットダウンの開始または認識の詳細については、「 Schannel 接続のシャットダウン」を参照してください。

TLS 1.0 を使用している場合は、メッセージ全体を復号化するために、この関数を複数回呼び出し、各呼び出しの入力バッファーを調整することが必要になる場合があります。

DecryptMessage (Schannel) 関数は、アプリケーション データ以外のハンドシェイク後 TLS プロトコル メッセージを受信すると、SEC_I_RENEGOTIATEを返します。 DecryptMessage (Schannel) 関数がSEC_I_RENEGOTIATEを返すと、それ以降の EncryptMessage() 呼び出しと DecryptMessage() 呼び出しは、SEC_E_CONTEXT_EXPIREDで失敗します。 アプリケーションは、 AcceptSecurityContext (Schannel) ( サーバー側) または InitializeSecurityContext (Schannel) ( クライアント側) を呼び出し、DecryptMessage() から返されたSECBUFFER_EXTRAを渡すことによって、この状況を処理します。 この最初の呼び出しで値が返された後、アプリケーションが新しい接続を作成しているかのように続行します。 その後、アプリケーションは EncryptMessage() と DecryptMessage() の呼び出しを続行できます。 詳細については、「 Schannel セキュリティ コンテキストの作成」を参照してください。

必要条件

要件
サポートされている最小のクライアント Windows XP (デスクトップ アプリのみ)
サポートされている最小のサーバー Windows Server 2003 (デスクトップ アプリのみ)
ヘッダー Sspi.h (Security.h を含む)
ライブラリ Secur32.lib
[DLL] Secur32.dll

関連項目