CryptAcquireContextW 関数 (wincrypt.h)

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

この関数は、まず dwProvType パラメーターと pszProvider パラメーターで説明されている特性を持つ CSP の検索を試みます。 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 に設定されている場合、 pszContainerNULL に設定する必要があります。 ただし、スマート カード 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 で指定された名前を持つ新しいキー コンテナーを作成します。 pszContainerNULL の場合、既定の名前のキー コンテナーが作成されます。
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 で指定されたキー コンテナーを削除します。 pszContainerNULL の場合、既定の名前のキー コンテナーが削除されます。 キー コンテナー内のすべての キー ペア も破棄されます。

このフラグが設定されている場合、 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 で定義されている可能性のあるエラー コードの一部を次に示します。

リターン コード/値 Description
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 (デスクトップ アプリのみ)
対象プラットフォーム Windows
ヘッダー wincrypt.h
Library Advapi32.lib
[DLL] Advapi32.dll

こちらもご覧ください

CryptGenKey

CryptGetProvParam

CryptReleaseContext

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

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