我在这里从 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证书存储,但由于我不知道如何移动,我使用导出-删除-导入序列。
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 是我用 C++ 编写的程序,用于将给定的 PFX 导入给定服务的个人证书存储区,在我的例子中是 MSMQ。
省略所有的错误处理,相关的 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 失败并显示消息An error occurred during encoding or decode operation。如果我调用PFXIsPFXBlob
API,它会返回 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。