こちらのMSDNフォーラムから質問を再投稿しています。
この問題は、Windowsサービスに関連付けられている個人証明書ストアに証明書をインポートすることに関係しています。
私のマシンの名前はil-mark-lapです(マシンはこの名前でping可能です)。
プロセス:
1.自己署名認証局の証明書があります。NCCAと呼びましょう。その秘密鍵は別のマシンに存在します。dev-profilerで参照してみましょう。
dev-profiler> makecert -n "CN=NCCA" -sr localmachine -ss root -a sha1 -cy authority -r -sv NCCA.pvk NCCA.cer
2. il-mark-lapマシン証明書は、dev-profilerで作成され、il-mark-lapのLocalComputer\My証明書ストアにインポートされます。認証局(NCCA)をLocalComputer \ Root証明書ストアに移動する必要があることに注意してください。ただし、移動方法がわからないため、export-delete-importシーケンスを使用します。
dev-profiler> makecert -n "CN=il-mark-lap" -sr CurrentUser -ss My -cy end -pe -sky exchange -a sha1 -is Root -ir LocalMachine -in NCCA
dev-profiler> certutil -user -exportpfx -p 123 il-mark-lap il-mark-lap.pfx
dev-profiler> certutil -user -delstore My il-mark-lap
il-mark-lap> cscript CStore.vbs import -l LM -s My -e il-mark-lap.pfx 123
il-mark-lap> cscript CStore.vbs export -l LM -s My -subject NCCA NCCA.cer
il-mark-lap> cscript CStore.vbs delete -noprompt -l LM -subject NCCA My
il-mark-lap> cscript CStore.vbs import -l LM -s Root NCCA.cer
3. il-mark-lapマシン証明書は、LocalComputer \My証明書ストアからMSMQ\My証明書ストア(メッセージキューサービスの個人証明書ストア)にコピーされます。繰り返しになりますが、コピー方法がわからないため、エクスポートとインポートのシーケンスを使用します。
il-mark-lap> cscript CStore.vbs export -l LM -s My -subject il-mark-lap tmp.pfx
il-mark-lap> ImportPfxIntoSrvCertStore MSMQ tmp.pfx 123
ImportPfxIntoSrvCertStoreは、指定されたPFXを指定されたサービス(私の場合はMSMQ)の個人証明書ストアにインポートするためにC++で記述されたプログラムです。
すべてのエラー処理を省略して、関連するC++コードは次のとおりです。
CSafeHandle pfxFileHandle(::CreateFile(wszPfxFilePath, FILE_READ_DATA, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0));
CSafeHandle pfxFileMapping(::CreateFileMapping(pfxFileHandle, 0, PAGE_READONLY, 0, 0, 0));
CSafeMapViewOfFile pfxFileBuffer(::MapViewOfFile(pfxFileMapping, FILE_MAP_READ, 0, 0, 0));
CRYPT_DATA_BLOB blob;
blob.cbData = ::GetFileSize(pfxFileHandle, 0);
blob.pbData = LPBYTE(LPVOID(pfxFileBuffer));
CSafeCertStoreHandle pfxStore(::PFXImportCertStore(&blob, wszPassword, CRYPT_MACHINE_KEYSET | CRYPT_EXPORTABLE));
CSafeCertStoreHandle serviceStore(::CertOpenStore(CERT_STORE_PROV_SYSTEM, 0, NULL, CERT_SYSTEM_STORE_SERVICES, wszCertificateStoreName));
PCCERT_CONTEXT pctx = NULL;
while (NULL != (pctx = ::CertEnumCertificatesInStore(pfxStore, pctx)))
{
::CertAddCertificateContextToStore(serviceStore, pctx, CERT_STORE_ADD_REPLACE_EXISTING, NULL);
}
CSafeXXXHandle
およびクラスを無視しCSafeMapViewOfFile
ます。これらは単純なハンドル/バッファーホルダーであり、デストラクタでそれぞれのハンドル/バッファーを解放します(「リソース取得は初期化です」デザインパターン)。
とにかく、PFXImportCertStore
APIは「エンコードまたはデコード操作中にエラーが発生しました」というメッセージで失敗します。APIを呼び出すと、PFXIsPFXBlob
FALSEが返されます。
コードの先頭にあるLocalsデバッガービューは次のとおりです。
+ wszPfxFilePath 0x00774e0c "tmp.pfx" const wchar_t *
+ wszCertificateStoreName 0x002cf7f4 "MSMQ\My" const wchar_t *
+ wszPassword 0x00774e1c "123" const wchar_t *
したがって、すべてのパラメータが正しいようです。
何が悪いのかわかりません。インポートされるPFXファイルは、MMCコンソールを使用して問題なくインポートされるため、完全に正しいものです。
ちなみに、私はこの記事にある例に基づいてコードを作成しました-http://www.codeguru.com/Cpp/IN/internet/security/article.php/c6211
編集
マシン証明書をLocalComputer\MyからMSMQ\Myにコピーするには、非対話型の手順が必要であることを強調したいと思います。