次の方法で共有


CryptAcquireContextW 関数 (wincrypt.h)

重要 この API は非推奨です。 新規および既存のソフトウェアでは、Cryptography Next Generation API の使用を開始する必要があります。 Microsoft は、今後のリリースでこの API を削除する可能性があります。
 
CryptAcquireContext 関数は、特定の 暗号化サービス プロバイダー (CSP) 内で 特定の キー コンテナーへのハンドルを取得するために使用されます。 この返されたハンドルは、選択した CSP を使用する CryptoAPI 関数 呼び出しで使用されます。

この関数は、まず、dwProvType で説明されている特性を持つ CSP を検索し、pszProvider パラメーターを しようとします。 CSP が見つかった場合、関数は、pszContainer パラメーターで指定された名前と一致する CSP 内のキー コンテナーの検索を試みます。 コンテキスト と、証明書の 公開キー に関連付けられている 秘密キー のキー コンテナーを取得するには、CryptAcquireCertificatePrivateKeyを使用します。

dwFlagsの適切な設定により、この関数はキー コンテナーを作成および破棄することもでき、秘密キーへのアクセスが必要ない場合は、一時キー コンテナーを使用して CSP へのアクセスを提供することもできます。

構文

BOOL CryptAcquireContextW(
  [out] HCRYPTPROV *phProv,
  [in]  LPCWSTR    szContainer,
  [in]  LPCWSTR    szProvider,
  [in]  DWORD      dwProvType,
  [in]  DWORD      dwFlags
);

パラメーター

[out] phProv

CSP のハンドルへのポインター。 CSP の使用が完了したら、CryptReleaseContext 関数を呼び出してハンドルを解放します。

[in] szContainer

キー コンテナー名。 これは、CSP に対するキー コンテナーを識別する null で終わる文字列です。 この名前は、キーの格納に使用されるメソッドとは無関係です。 一部の CSP は、キー コンテナーを内部 (ハードウェア) に格納し、一部はシステム レジストリを使用し、他の CSP はファイル システムを使用します。 ほとんどの場合、dwFlags が CRYPT_VERIFYCONTEXT に設定されている場合、pszContainer NULLを に設定する必要があります。 ただし、スマート カード CSP などのハードウェア ベースの CSP の場合は、指定されたコンテナー内の公開されている情報にアクセスできます。

pszContainer パラメーターの使用方法の詳細については、「解説」を参照してください。

[in] szProvider

使用する CSP の名前を含む null で終わる文字列。

このパラメーターが NULL場合は、ユーザーの既定のプロバイダーが使用されます。 詳細については、「暗号化サービス プロバイダー コンテキストの」を参照してください。 使用可能な暗号化プロバイダーの一覧については、「暗号化プロバイダー名の」を参照してください。

アプリケーションは、CryptGetProvParam 関数を使用して、dwParam パラメーターのPP_NAME CSP 値を読み取ることで、使用中の CSP の名前を取得できます。

既定の CSP は、オペレーティング システムのリリース間で変更される可能性があります。 異なるオペレーティング システム プラットフォームでの相互運用性を確保するには、既定の CSP を使用するのではなく、このパラメーターを使用して CSP を明示的に設定する必要があります。

[in] dwProvType

取得するプロバイダーの種類を指定します。 定義済みのプロバイダーの種類については、暗号化プロバイダーの種類で説明します。

[in] dwFlags

次のフラグの 1 つ以上。 ほとんどのアプリケーションでは、デジタル署名を作成したりメッセージを復号化したりする必要がない限り、CRYPT_VERIFYCONTEXT フラグを設定する必要があります。

価値 意味
CRYPT_VERIFYCONTEXT
呼び出し元は、永続化された秘密キーにアクセスする必要はありません。 エフェメラル キーを使用するアプリ、または ハッシュ暗号化、デジタル署名 検証のみを実行するアプリでは、このフラグを設定する必要があります。 署名を作成したり、メッセージの暗号化を解除したりするアプリケーションのみが、秘密キー にアクセスする必要があります (このフラグは設定しないでください)。

ファイル ベース CSP の場合、このフラグが設定されている場合、pszContainer パラメーターを NULL設定する必要があります。 アプリケーションは、公開キーと秘密キーのペアの永続化された秘密キーにアクセスできません。 このフラグを設定すると、一時的な 公開キーと秘密キーのペア 作成できますが、永続化されません。

スマート カード CSP などのハードウェア ベースの CSP の場合、pszContainer パラメーターが NULL または空白 場合、このフラグは、キーへのアクセスが不要であり、ユーザーに UI を表示する必要がないことを意味します。 このフォームは、CSP に接続して機能のクエリを実行するために使用されますが、実際にはキーを使用しません。 pszContainer パラメーターが NULL ではなく、空白でない場合、このフラグは、指定されたコンテナー内で公開されている情報にのみアクセスする必要があることを意味します。 CSP は PIN を要求しないでください。 個人情報 (CryptSignHash 関数など) へのアクセスは失敗します。

CryptAcquireContext 呼び出されると、多くの CSP は、キー コンテナー内の秘密キーへのアクセスを許可する前に、所有ユーザーからの入力を必要とします。 たとえば、秘密キーを暗号化して、使用する前にユーザーのパスワードを要求できます。 ただし、CRYPT_VERIFYCONTEXT フラグを指定した場合、秘密キーへのアクセスは必要なく、ユーザー インターフェイスをバイパスできます。

CRYPT_NEWKEYSET
pszContainerで指定された名前 新しいキー コンテナーを作成します。 pszContainer NULL場合は、既定の名前のキー コンテナーが作成されます。
CRYPT_MACHINE_KEYSET
既定では、キーとキー コンテナーはユーザー キーとして格納されます。 基本プロバイダーの場合、これはユーザー キー コンテナーがユーザーのプロファイルに格納されることを意味します。 管理者によってこのフラグなしで作成されたキー コンテナーには、キー コンテナーを作成しているユーザーと管理特権を持つユーザーのみがアクセスできます。

Windows XP: 管理者によってこのフラグなしで作成されたキー コンテナーには、キー コンテナーとローカル システム アカウントを作成しているユーザーのみがアクセスできます。

管理者ではないユーザーがこのフラグなしで作成したキー コンテナーには、キー コンテナーとローカル システム アカウントを作成しているユーザーのみがアクセスできます。

CRYPT_MACHINE_KEYSET フラグを他のすべてのフラグと組み合わせて、対象のキー コンテナーがコンピューター キー コンテナーであり、CSP がそのように扱うことを示すことができます。 基本プロバイダーの場合、これは、キー コンテナーを作成したコンピューターにキーがローカルに格納されることを意味します。 キー コンテナーをコンピューター コンテナーにする場合は、コンピューター コンテナーを参照する CryptAcquireContext を するすべての呼び出しでCRYPT_MACHINE_KEYSET フラグを使用する必要があります。 管理者によってCRYPT_MACHINE_KEYSETで作成されたキー コンテナーには、その作成者と管理者 特権を持つユーザーのみがアクセスできます、コンテナーへのアクセス権が CryptSetProvParamを使用して付与 場合を除きます。

Windows XP: 管理者によってCRYPT_MACHINE_KEYSETで作成されたキー コンテナーは、CryptSetProvParamを使用してコンテナーへのアクセス権が付与されていない限り、その作成者とローカル システム アカウントによってのみアクセスできます。

管理者ではないユーザーがCRYPT_MACHINE_KEYSETで作成したキー コンテナーは、CryptSetProvParamを使用 してコンテナーへのアクセス権が付与されていない限り、その作成者とローカル システム アカウントによってのみアクセスできます。

CRYPT_MACHINE_KEYSET フラグは、対話形式でログオンしなかったサービスまたはユーザー アカウントからユーザーがアクセスしている場合に便利です。 キー コンテナーが作成されると、ほとんどの CSP は公開キーと秘密キーのペアを自動的に作成しません。 これらのキーは、CryptGenKey 関数を使用して別の手順として作成する必要があります。

CRYPT_DELETEKEYSET
pszContainerで指定された キー コンテナー 削除します。 pszContainer NULL場合、既定の名前のキー コンテナーが削除されます。 キー コンテナー内 キー ペアもすべて破棄されます。

このフラグが設定されている場合、phProv 返される値は未定義であるため、CryptReleaseContext 関数を後で呼び出す必要はありません。

CRYPT_SILENT
アプリケーションは、この コンテキストのユーザー インターフェイス (UI) を CSP に表示しないように要求します。 CSP が操作する UI を表示する必要がある場合、呼び出しは失敗し、NTE_SILENT_CONTEXTエラー コードが最後のエラーとして設定されます。 さらに、CRYPT_SILENT フラグで取得されたコンテキストを持つCRYPT_USER_PROTECTED フラグを使用して CryptGenKey を する呼び出しが行われた場合、呼び出しは失敗し、CSP はNTE_SILENT_CONTEXT設定します。

CRYPT_SILENTは、CSP で UI を表示できないアプリケーションで使用することを目的としています。

CRYPT_DEFAULT_CONTAINER_OPTIONAL
ハッシュと対称キー操作に使用できるスマート カード CSP のコンテキストを取得しますが、PIN を使用したスマート カードへの認証を必要とする操作には使用できません。 この種類のコンテキストは、CryptSetProvParamを使用して PIN を設定するなど、空のスマート カードに対する操作 実行するために最もよく使用されます。 このフラグは、スマート カード CSP でのみ使用できます。

Windows Server 2003 および Windows XP: このフラグはサポートされていません。

戻り値

関数が成功した場合、関数は 0 以外 (TRUE) を返します。

関数が失敗した場合は、0 (FALSE) を返します。 拡張エラー情報については、GetLastError呼び出します。

NTE で開始されるエラー コードは、使用されている特定の CSP によって生成されます。 Winerror.h で定義されている可能性のあるエラー コードの一部を次に示します。

戻りコード/値 形容
ERROR_BUSY
107L
一部の CSP は、CRYPT_DELETEKEYSET フラグ値が設定され、別のスレッドまたは プロセス がこの キー コンテナーを使用している場合に、このエラーを設定します。
ERROR_FILE_NOT_FOUND
2L
ユーザーのプロファイルが読み込まれず、見つかりません。 これは、IUSR_ComputerName アカウントなど、アプリケーションがユーザーを偽装した場合に発生します。
ERROR_INVALID_PARAMETER
87L
パラメーターの 1 つに無効な値が含まれています。 これは、多くの場合、無効なポインターです。
ERROR_NOT_ENOUGH_MEMORY
8L
操作中にオペレーティング システムのメモリが不足しました。
NTE_BAD_FLAGS
0x80090009L
dwFlags パラメーターの値が無効です。
NTE_BAD_KEY_STATE
0x8009000BL
秘密キーが暗号化されてから、ユーザー パスワードが変更されました。
NTE_BAD_KEYSET
0x80090016L
キー コンテナーを開くことができませんでした。 このエラーの一般的な原因は、キー コンテナーが存在しないことです。 キー コンテナーを作成するには、CRYPT_NEWKEYSET フラグ 使用して CryptAcquireContext を呼び出します。 このエラー コードは、既存のキー コンテナーへのアクセスが拒否されたことを示すこともできます。 コンテナーへのアクセス権は、CryptSetProvParam使用して、キー セットの作成者が付与できます。
NTE_BAD_KEYSET_PARAM
0x8009001FL
pszContainer または pszProvider パラメーター が無効な値に設定されています。
NTE_BAD_PROV_TYPE
0x80090014L
dwProvType パラメーターの値が範囲外です。 すべてのプロバイダーの種類は、1 ~ 999 の範囲である必要があります。
NTE_BAD_SIGNATURE
0x80090006L
プロバイダー DLL 署名を検証できませんでした。 DLL またはデジタル署名のいずれかが改ざんされています。
NTE_EXISTS
0x8009000FL
dwFlags パラメーターはCRYPT_NEWKEYSETされていますが、キー コンテナーは既に存在します。
NTE_KEYSET_ENTRY_BAD
0x8009001AL
pszContainer キー コンテナーが見つかりましたが、破損しています。
NTE_KEYSET_NOT_DEF
0x80090019L
要求されたプロバイダーが存在しません。
NTE_NO_MEMORY
0x8009000EL
操作中に CSP のメモリが不足しました。
NTE_PROV_DLL_NOT_FOUND
0x8009001EL
プロバイダー DLL ファイルが存在しないか、現在のパスにありません。
NTE_PROV_TYPE_ENTRY_BAD
0x80090018L
dwProvType で指定 プロバイダーの種類が破損しています。 このエラーは、ユーザーの既定の CSP リストまたはコンピューターの既定の CSP リストのいずれかに関連する場合があります。
NTE_PROV_TYPE_NO_MATCH
0x8009001BL
dwProvType で指定されたプロバイダーの種類が、見つかったプロバイダーの種類と一致しません。 このエラーは、pszProvider が実際の CSP 名 指定した場合にのみ発生します。
NTE_PROV_TYPE_NOT_DEF
0x80090017L
dwProvTypeで指定されたプロバイダーの種類 エントリが存在しません。
NTE_PROVIDER_DLL_FAIL
0x8009001DL
プロバイダー DLL ファイルを読み込めなかったか、初期化に失敗しました。
NTE_SIGNATURE_FILE_BAD
0x8009001CL
署名を確認する前に、DLL ファイル イメージの読み込み中にエラーが発生しました。

備考

pszContainer パラメーターは、キーを保持するために使用されるコンテナーの名前を指定します。 各コンテナーには、1 つのキーを含めることができます。 キーの作成時に既存のコンテナーの名前を指定すると、新しいキーによって前のコンテナーが上書きされます。

CSP 名とキー コンテナー名の組み合わせによって、システム上の 1 つのキーが一意に識別されます。 あるアプリケーションがキー コンテナーを使用しているときにキー コンテナーを変更しようとすると、予期しない動作が発生する可能性があります。

pszContainer パラメーターを NULL設定すると、既定のキー コンテナー名が使用されます。 この方法で Microsoft ソフトウェア CSP が呼び出されると、CryptAcquireContext 関数が呼び出されるたびに新しいコンテナーが作成されます。 ただし、この点では、CSP の動作が異なる場合があります。 特に、CSP には、CSP にアクセスするすべてのアプリケーションによって共有される 1 つの既定のコンテナーがある場合があります。 そのため、アプリケーションでは、秘密キーを格納するために既定のキー コンテナーを使用しないでください。 代わりに、dwFlags パラメーターに CRYPT_VERIFYCONTEXT フラグを渡してキー ストレージを禁止するか、別のアプリケーションで使用される可能性が低いアプリケーション固有のコンテナーを使用します。

アプリケーションは、CryptGetProvParam 関数を使用してPP_CONTAINER値を読み取ることで、使用中のキー コンテナーの名前を取得できます。

パフォーマンス上の理由から、pszContainer パラメーターを NULL に設定し、dwFlags パラメーターを永続化キーを必要としないすべての状況で CRYPT_VERIFYCONTEXT することをお勧めします。 特に、次のシナリオでは、pszContainer パラメーターを NULL に設定し、dwFlags パラメーターを CRYPT_VERIFYCONTEXT することを検討してください。

  • ハッシュを作成しています。
  • データを暗号化または復号化するための対称キーを生成しています。
  • データを暗号化または復号化するために、ハッシュから対称キーを派生しています。
  • 署名を確認しています。 CryptImportKey または CryptImportPublicKeyInfo使用して、PUBLICKEYBLOB または証明書から公開キーをインポートできます。 公開キーのみをインポートする場合は、CRYPT_VERIFYCONTEXT フラグを使用してコンテキストを取得できます。
  • 対称キーをエクスポートする予定ですが、暗号化コンテキストの有効期間内にはインポートしません。 過去 2 つのシナリオの公開キーのみをインポートする予定の場合は、CRYPT_VERIFYCONTEXT フラグを使用してコンテキストを取得できます。
  • 秘密キー操作を実行していますが、キー コンテナーに格納されている永続化された秘密キーを使用していません。
秘密キー操作を実行する場合、コンテキストを取得する最善の方法は、コンテナーを開こうとすることです。 この試行がNTE_BAD_KEYSETで失敗した場合は、CRYPT_NEWKEYSET フラグを使用してコンテナーを作成します。

次の例は、暗号化コンテキストの取得と、キー コンテナー内の公開キーと秘密キーのペアへのアクセスを示しています。 要求されたキー コンテナーが存在しない場合は、作成されます。

この例の完全なコンテキストを含む例については、「例 C プログラム: キー コンテナーの作成とキーの生成」を参照してください。 その他の例については、「サンプル C プログラム: CryptAcquireContextの使用」を参照してください。

//-------------------------------------------------------------------
// Declare and initialize variables.

HCRYPTPROV hCryptProv = NULL;        // handle for a cryptographic
                                     // provider context
LPCSTR UserName = "MyKeyContainer";  // name of the key container
                                     // to be used
//-------------------------------------------------------------------
// Attempt to acquire a context and a key
// container. The context will use the default CSP
// for the RSA_FULL provider type. DwFlags is set to zero
// to attempt to open an existing key container.

if(CryptAcquireContext(
   &hCryptProv,               // handle to the CSP
   UserName,                  // container name 
   NULL,                      // use the default provider
   PROV_RSA_FULL,             // provider type
   0))                        // flag values
{
    printf("A cryptographic context with the %s key container \n", 
  UserName);
    printf("has been acquired.\n\n");
}
else
{ 
//-------------------------------------------------------------------
// An error occurred in acquiring the context. This could mean
// that the key container requested does not exist. In this case,
// the function can be called again to attempt to create a new key 
// container. Error codes are defined in Winerror.h.
 if (GetLastError() == NTE_BAD_KEYSET)
 {
   if(CryptAcquireContext(
      &hCryptProv, 
      UserName, 
      NULL, 
      PROV_RSA_FULL, 
      CRYPT_NEWKEYSET)) 
    {
      printf("A new key container has been created.\n");
    }
    else
    {
      printf("Could not create a new key container.\n");
      exit(1);
    }
  }
  else
  {
      printf("A cryptographic service handle could not be "
          "acquired.\n");
      exit(1);
   }
  
} // End of else.
//-------------------------------------------------------------------
// A cryptographic context and a key container are available. Perform
// any functions that require a cryptographic provider handle.

//-------------------------------------------------------------------
// When the handle is no longer needed, it must be released.

if (CryptReleaseContext(hCryptProv,0))
{
  printf("The handle has been released.\n");
}
else
{
  printf("The handle could not be released.\n");
}

手記

wincrypt.h ヘッダーは、UNICODE プリプロセッサ定数の定義に基づいて、この関数の ANSI または Unicode バージョンを自動的に選択するエイリアスとして CryptAcquireContext を定義します。 エンコードに依存しないエイリアスをエンコードに依存しないコードと組み合わせて使用すると、コンパイルエラーやランタイム エラーが発生する不一致が発生する可能性があります。 詳細については、「関数プロトタイプの 規則」を参照してください。

必要条件

要件 価値
サポートされる最小クライアント Windows XP [デスクトップ アプリのみ]
サポートされる最小サーバー Windows Server 2003 [デスクトップ アプリのみ]
ターゲット プラットフォーム の ウィンドウズ
ヘッダー wincrypt.h
ライブラリ Advapi32.lib
DLL Advapi32.dll

関連項目

CryptGenKey

CryptGetProvParam

CryptReleaseContext

サービス プロバイダー関数の

暗号化サービス プロバイダーの に関するスレッドの問題を する