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