大多数git服务器都会捕获一个“推送”操作,该操作由进行推送的经过身份验证的用户执行,其中包括哪些提交。这很难伪造,除非你对服务器有管理员权限或访问服务器的存储。
在客户机上,当进行提交时,会捕获提交元数据,但不能保证数据是正确的。即使用户在提交上签名,签名也可能在错误的日期进行。GPG/PGP没有使用外部时间服务器权限将时间签名到签名中。
但这将防止用户更改其他用户的提交(及其时间)。
满足所有需求的解决方案是对时间服务器使用SMIME签名。要做到这一点,您的每个开发人员都需要一个代码签名证书,并为他们配置它和一个时间服务器来验证签名者和签名时间。
客户机上的预提交钩子可以防止时间设置不正确时出现意外提交问题,但由于钩子需要在每个克隆之后安装(并且可以轻松删除),因此它对对手的安全性很低。
服务器上的预接收钩子可以防止意外推送到包含“旧”提交的中央服务器,但在从其他位置(fork、mirror等)导入存储库时可能会导致问题。
如果本地回购已将时间更改为服务器的安全时间窗口内,则两者都不会阻止推送。
在这里,最好的方法是信任服务器上的“推送”元数据,以便准确地确定数据何时进入组织以及旧数据何时被强制推送。可能与使用SMIME证书和时间服务器的注销提交相结合。
见:
https://www.glennwatson.net/posts/code-signing-github
GitHub设置
我假设您希望对所有存储库使用S/MIME签名。GitHub指南中还有其他选项。由于时间戳权限存在问题,我们将生成一个批处理文件来运行smimesign。
-
安装S/MIME标志。
-
创建一个位于smimesign路径中的批处理文件。对于windows,批处理文件示例(您可以将其命名为sign.cmd)
Copy to clipboard@echo off
smimesign.exe --timestamp-authority http://timestamp.digicert.com %*
-
告诉git使用smimesign。从命令行运行:
git config --global gpg.x509.program c:/path/to/sign.cmd
git config --global gpg.format x509
git config --global commit.gpgsign true
-
找到你想要签名的钥匙。跑
smimesign --list-keys
然后找到你想要签名的钥匙的序列号。复制密钥的序列号,以便将其粘贴到下一个命令中。确保使用的是序列号,而不是ID。
-
从命令行设置要使用的键
git config --global user.signingkey a2dfa7e8c9c4d1616f1009c988bb70f
现在,每次提交时,它都会要求您输入之前设置的密码。
另见:
Sign git commit with x509 certificate in corporate environment