如何将计算机证书导入与Windows服务关联的个人证书存储中?

时间:2011-01-18 20:25:27

标签: windows certificate ssl-certificate cryptoapi

我将在MSDN论坛中重新发布my question

此问题与将证书导入与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 上创建并导入 LocalComputer \ My il-mark-lap 上的证书存储区。请注意,必须将权限证书( NCCA )移动到 LocalComputer \ Root 证书存储区,但由于我不知道如何移动,我使用export-delete - 进口顺序。

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 < / strong>证书存储区(消息队列服务个人证书存储区)。同样,我不知道如何复制,所以我使用导出导入序列。

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);
}

忽略CSafeXXXHandleCSafeMapViewOfFile类,这些是简单的句柄/缓冲区持有者,在析构函数中释放相应的句柄/缓冲区(“资源获取是初始化”设计模式)。

无论如何,PFXImportCertStore API失败并显示消息编码或解码操作期间发生错误。如果我调用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/I-N/internet/security/article.php/c6211

修改

我想强调一点,我需要一个非交互式程序将机器证书从LocalComputer \ My复制到MSMQ \ My。

1 个答案:

答案 0 :(得分:1)

我会尝试使用证书存储mmc插件:

,而不是使用程序
  • 启动mmc.exe,这将为您提供处于创作模式的MMC。
  • 点击文件 - &gt;添加/删除管理单元
  • 查找并双击“证书”。这将弹出一个对话框,您可以在其中选择要管理的证书存储。
  • 我认为“服务帐户”是适合您的选择
  • 点击下一步
  • 如果您已经在il-mark-lap上选择本地,否则请选择“另一台计算机”。 AFAIK,您必须使用域管理员帐户登录才能使用此功能。
  • 点击下一步
  • 选择您的服务
  • 点击完成。

此时,您应该已经可以访问服务的证书存储空间了。如果你想更频繁地这样做,那么我建议你也这样做:

  • 右键单击树中的“证书”,然后选择“从此处新建窗口”
  • 切换回控制台根窗口并关闭它
  • 将您的艺术作品保存为.msc文件

修改

在保存之前,从树中选择“证书”,然后选择查看 - &gt;选项。如果您愿意,可以在这里选择查看“物理证书商店”。