如何将机器证书导入与 Windows 服务关联的个人证书存储?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4728650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to import machine certificate into the Personal certificate store associated with a Windows service?
提问by mark
I am reposting my questionfrom the MSDN forums here.
我在此处从 MSDN 论坛重新发布我的问题。
This problem has to do with importing a certificate into the personal certificate store associated with a windows service.
此问题与将证书导入与 Windows 服务关联的个人证书存储区有关。
The name of my machine is il-mark-lap(the machine is pingable by this name).
我的机器的名字是il-mark-lap(机器可以通过这个名字 ping 通)。
The process:
过程:
1.There is a self signed authority certificate, let us call it NCCA. Its private key lives on another machine, let us refer it by dev-profiler.
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.The il-mark-lapmachine certificate is created on dev-profilerand imported to the LocalComputer\Mycertificate store on il-mark-lap. Note, that the authority certificate (NCCA) has to be moved to LocalComputer\Rootcertificate store, but since I do not know how to move, I use the export-delete-import sequence.
2.在IL-标记圈机证书上创建DEV-探查,并导入到LocalComputer \我的证书存储IL-标记圈。请注意,授权证书 ( 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.The il-mark-lapmachine certificate is copied from LocalComputer\Mycertificate store into MSMQ\Mycertificate store (Message Queuing service Personal certificate store). Again, I do not know how to copy, so I use the export-import sequence.
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
Where ImportPfxIntoSrvCertStore is my program written in C++ to import the given PFX into the Personal certificate store of the given service, MSMQ in my case.
其中 ImportPfxIntoSrvCertStore 是我用 C++ 编写的程序,用于将给定的 PFX 导入给定服务的个人证书存储,在我的情况下为 MSMQ。
Omitting all the error handling, the relevant C++ code is this:
省略所有的错误处理,相关的 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);
}
Ignore the CSafeXXXHandleand CSafeMapViewOfFileclasses, these are simple handle/buffer holders, releasing the respective handle/buffer in the destructor ("resource acquisition is initialization" design pattern).
忽略CSafeXXXHandle和CSafeMapViewOfFile类,这些是简单的句柄/缓冲区持有者,在析构函数中释放相应的句柄/缓冲区(“资源获取即初始化”设计模式)。
Anyway, the PFXImportCertStoreAPI fails with the message An error occurred during encode or decode operation. If I call the PFXIsPFXBlobAPI, it returns FALSE.
无论如何,PFXImportCertStoreAPI 失败并显示消息An error occurred during encode or decode operation。如果我调用PFXIsPFXBlobAPI,它返回 FALSE。
Here is the Locals debugger view at the start of the code:
这是代码开头的 Locals 调试器视图:
+ wszPfxFilePath 0x00774e0c "tmp.pfx" const wchar_t *
+ wszCertificateStoreName 0x002cf7f4 "MSMQ\My" const wchar_t *
+ wszPassword 0x00774e1c "123" const wchar_t *
So, all the parameters seem to be correct.
因此,所有参数似乎都是正确的。
I have no idea what is wrong. The PFX file being imported is absolutely correct, because it is imported flawlessly using the MMC console.
我不知道出了什么问题。正在导入的 PFX 文件是绝对正确的,因为它是使用 MMC 控制台完美导入的。
Incidentally, I have based my code on the example found in this article - http://www.codeguru.com/Cpp/I-N/internet/security/article.php/c6211
顺便说一句,我的代码基于本文中的示例 - http://www.codeguru.com/Cpp/IN/internet/security/article.php/c6211
Edit
编辑
I would like to emphasize that I need a non interactive procedure to copy the machine certificate from LocalComputer\My to MSMQ\My.
我想强调的是,我需要一个非交互式过程来将机器证书从 LocalComputer\My 复制到 MSMQ\My。
回答by Fozi
Instead of using a program I would try to use the certificate store mmc plugin:
我会尝试使用证书存储 mmc 插件,而不是使用程序:
- Start
mmc.exe, this will give you the MMC in authoring mode. - Click File -> Add/remove Snap-in
- Find and double-click "Certificates". This will pop up a dialog where you can select which certificate storage you want to administer.
- I think "Service Account" is the appropriate selection for you here
- Click next
- Select local if you are on il-mark-lap already, otherwise select "Another computer". AFAIK, you will have to be logged in with a domain administrator account for this to work though.
- Click next
- Select your service
- click finish.
- 开始
mmc.exe,这将为您提供创作模式的 MMC。 - 单击文件 -> 添加/删除管理单元
- 找到并双击“证书”。这将弹出一个对话框,您可以在其中选择要管理的证书存储。
- 我认为“服务帐户”是您的合适选择
- 点击下一步
- 如果您已经在 il-mark-lap 上,请选择本地,否则选择“另一台计算机”。AFAIK,您必须使用域管理员帐户登录才能正常工作。
- 点击下一步
- 选择您的服务
- 点击完成。
At this point you should already be able to access the certificate storage for your service. If you want to do this more often then I suggest you do this as well:
此时,您应该已经能够访问您的服务的证书存储。如果你想更频繁地这样做,那么我建议你也这样做:
- Right-click "Certificates" in the tree and select "New Window from Here"
- Switch back to the console root window and close it
- Save your work of art to a .msc file
- 右键单击树中的“证书”并选择“从此处新建窗口”
- 切换回控制台根窗口并关闭它
- 将您的艺术作品保存为 .msc 文件
Edit
编辑
Before you save, select "Certificates" from the tree, and then View -> Options. Here you can select to see the "Physical Certificate stores" if you like.
在保存之前,从树中选择“证书”,然后选择“查看”->“选项”。如果您愿意,您可以在此处选择查看“物理证书存储”。

