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