自动化代码签名 - 保护私钥

13
我希望自动化一些ClickOnce部署文件的代码签名-应用程序exe和清单。我使用signtool来完成这个任务。为了使私钥可用于签名并保护包含私钥(.pfx文件)的证书文件,我的计划是将证书安装到本地机器证书存储中,并带有不可导出的密钥 (我知道即使标记为不可导出,也有导出密钥的方法)。该机器是一个持续集成服务器,只会开放给少数人员使用。我希望设置的方式是每次需要使用私钥时都需要输入私钥密码。然后,我将设置一个自动化作业(使用Jenkins),该作业将需要一个构建参数,以收集私钥密码。在输入密码并在控制台输出时,将使用Mask Passwords插件来掩盖密码。
但是,我遇到了几个问题。首先,尽管在导入证书时有“启用强大的私钥保护。如果启用此选项,则每次应用程序使用私钥时都会提示您。”,但似乎仅在导入当前用户存储而不是本地机器存储时才可用。其次,即使此选项可用,signtool工具也没有提供在使用存储中的证书进行签名时设置密码的选项。密码参数'/p'仅适用于使用.pfx文件作为私钥来源('/f'选项)的情况。鉴于这一点,这似乎不是一个可行的选项。注意:即使“启用强大的私钥保护。”适用于机器存储中的证书,我的测试表明尝试使用启用此选项的证书时会弹出一个对话框请求允许使用它,这显然无法用于自动化作业。我最初认为“提示”意味着它会要求输入密码。我考虑的另一种选择是创建ACL来保护证书存储中的私钥。这可以通过右键单击证书并选择"所有任务..." | "管理私钥"对话框来完成。这将限制私钥的使用仅限于那些获得授权的用户。(注意:当没有权限的用户尝试使用私钥进行签名时,他们会收到"SignTool错误:找不到符合所有给定条件的证书"的消息。)然而,我不想给Jenkins构建服务使用的凭据访问权,因为任何构建作业都可以签署代码。我可以创建一个作业,执行一个脚本以特定用户身份运行签署命令。这将需要将域用户名和密码作为构建参数输入。我可以使用Jenkins Mask Passwords插件来实现这一点。不过我不太喜欢这个方法,因为我不确定Mask Passwords是否足以防止暴露域凭据,如果凭据被泄露,将不仅能获得私钥。
如果我放弃将证书存储在机器存储中的原始想法,那么就可以将证书pfx文件放置在构建机器上一个只有构建流程和签名用户拥有权限的ACL安全文件夹中。这样做将允许我创建一个构建作业来使用包含的私钥,同时不将文件暴露给其他可以访问该机器的人。为了使用私钥,构建参数需要收集私钥密码。
最后,还有一种选择是使用智能卡来存储证书,但我们决定不采用这种方法。
那么,我的问题是:有没有其他方法可以做到以下三点:1)保护私钥不被复制;2)防止未经授权的用户使用私钥签署代码;3)在授权用户提供私钥密码的情况下,使私钥可以被构建服务签名?
3个回答

6
首先,我将分别回答您的问题:
1. 保护私钥不被复制:只有加密硬件(智能卡或HSM)才能真正保护密钥不被复制。Windows证书存储(即使使用非可导出选项,如您所指出的)或PKCS#12(PFX)文件只提供虚假的保护感。
2. 防止未经授权的用户使用私钥签署代码:在我看来,这需要用户交互,例如输入密码或PIN码。如果将密码作为参数传递,则始终存在其他进程可以获取它的可能性,即从进程信息、日志等中获取。
3. 如果由授权用户提供私钥密码,则使私钥可由构建服务进行签名:通过CSP(Windows证书存储)访问的加密硬件(智能卡或HSM),并与交互式输入的PIN一起使用signtool应该没有任何问题。
我同意,对于自动构建服务来说,需要用户交互的要求可能并不方便,但是您可能需要在安全的带有用户交互的解决方案和不带用户交互的不太安全的解决方案之间进行选择。
方便但不太安全的解决方案1:我认为您已经找到了一个可以接受的解决方案,因为您没有提供其任何缺点。
然而,请注意,PFX文件不仅可以从实时系统中无法检测地复制,还可以从备份中复制。
方便但不太安全的解决方案2:将私钥存储在不需要输入PIN的智能卡上,并仅允许受信任的用户访问系统。这将确保您的私钥无法被复制,同时仍然可以轻松访问signtool。但是,这可能需要您拥有两个单独的构建服务器——一个没有智能卡可供所有用户访问,另一个只有受信任的用户才能访问智能卡。
不方便但安全的解决方案:将私钥存储在需要输入PIN的智能卡上,并在构建过程中要求用户交互(输入PIN)。
您还可以考虑以自签名代码签名证书对开发构建进行自动签名,并以受信任的代码签名证书手动签署公共发布构建。

1

我所能看到的唯一选择是使用HSM。

你可以生成由操作卡/卡组保护的私钥(例如,Thales就有这种类型的HSMs)。操作卡组可以设置配额,指定有多少个操作员必须在请求使用该私钥的应用程序之前插入卡片,才能使私钥可用。Thales还有一个支持此功能的CSP。

问题可能在于CSP将调用窗口显示用户必须插入卡片(并可选地输入该卡片的密码)。当您在某个可以登录的桌面用户帐户下运行构建服务器时,可以解决此问题。当您以此用户身份登录并启动构建服务器时,它必须请求使用私钥(例如通过签署某些虚拟文件)。Windows将弹出窗口,操作员(根据配额要求的数量)将逐一插入其卡,并可选地输入其密码。在插入所有必需卡后,密钥将可供您的构建服务器使用。任何其他应用程序(可能由其他用户启动)都将经过同样的过程来使用该密钥。如果您的构建服务器崩溃(构建服务器会崩溃吗?),则必须再次执行相同的过程。

HSM还具有防篡改保护功能,因此私钥在其中是相对安全的。很抱歉只谈到了Thales HSM,但我个人没有其他HSM的经验。

-1

似乎依赖于受密码保护的PFX文件而不是证书存储是安全的。即使在存放PFX的硬盘文件夹上没有ACL保护,拿走PFX文件的人也无法使用它来签署任何东西,除非他们也知道密码。

然后,在该计算机上设置一个参数化的Jenkins“签名”作业,完全封装PFX密码,以便没有人可以看到它。(我正在考虑某种脚本,可能是Powershell,转换为黑盒EXE。)授权的Jenkins作业可以链接到签名作业以完成签名。 EXE将记录每次使用它作为审计功能。只需要弄清如何防止未经授权使用签名作业...必须有一种方法可以做到这一点吧?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接