为什么 git 使用 GPG 密钥签名而不是使用 SSH 密钥?
Why does git sign with GPG keys rather than using SSH keys?
SSH 和 GPG 非对称密钥之间的区别是什么?为什么 git 支持使用 GPG 签名而不是使用 SSH 代理?
2021 年更新:
OpenSSH 8.2+ 可用(例如打包在 Git For Windows 2.33.1), and "it is now possible to sign arbitrary data with your SSH keys" (Andrew Ayer 中),包括 Git.
中的提交
Andrew 指向 git/git
PR 1041 "ssh signing: Add commit & tag signing/verification via SSH keys using ssh-keygen", now with Git 2.34(2021 年 11 月)
将有一个新值“ssh
”
set gpg.format = ssh
and user.signingkey
to a ssh public key string (like from an authorized_keys file) and commits/tags can be signed using the private key from your ssh-agent.
安德鲁补充道:
Always be wary of repurposing cryptographic keys for a different protocol. If not done carefully, there's a risk of cross-protocol attacks.
For example, if the structure of the messages signed by Git is similar to the structure of SSH protocol messages, an attacker might be able to forge Git artifacts by misappropriating the signature from an SSH transcript.
Fortunately, the structure of SSH protocol messages and the structure of messages signed by ssh-keygen are dissimilar enough that there is no risk of confusion.
来自:
Git 2.34(2021 年第 4 季度):使用 ssh public 加密进行对象和推送证书签名。
参见 commit 1bfb57f, commit f265f2d, commit 3326a78, commit facca53, commit 4838f62, commit fd9e226, commit 29b3157, commit 64625c7, commit b5726a5 (10 Sep 2021) by Fabian Stelzer (FStelzer
)。
(由 Junio C Hamano -- gitster
-- in commit 18c6653 合并,2021 年 10 月 25 日)
ssh signing
: verify signatures using ssh-keygen
Signed-off-by: Fabian Stelzer
To verify a ssh signature we first call ssh-keygen -Y find-principal
to look up the signing principal by their public key from the allowedSignersFile
.
If the key is found then we do a verify.
Otherwise we only validate the signature but can not verify the signers identity.
Verification uses the gpg.ssh.allowedSignersFile
(see ssh-keygen(1)
"ALLOWED SIGNERS") which contains valid public keys and a principal (usually user@domain
).
Depending on the environment this file can be managed by the individual developer or for example generated by the central repository server from known ssh keys with push access.
This file is usually stored outside the repository, but if the repository only allows signed commits/pushes, the user might choose to store it in the repository.
To revoke a key put the public key without the principal prefix into gpg.ssh.revocationKeyring
or generate a KRL (see ssh-keygen(1)
"KEY REVOCATION LISTS").
The same considerations about who to trust for verification as with the allowedSignersFile
apply.
Using SSH CA Keys with these files is also possible.
Add "cert-authority
" as key option between the principal and the key to mark it as a CA and all keys signed by it as valid for this CA.
See "CERTIFICATES" in ssh-keygen(1)
.
git config
现在包含在其 man page 中:
gpg.ssh.allowedSignersFile
A file containing ssh public keys which you are willing to trust.
The file consists of one or more lines of principals followed by an ssh
public key.
e.g.: user1@example.com,user2@example.com ssh-rsa AAAAX1...
See ssh-keygen(1)
"ALLOWED SIGNERS" for details.
The principal is only used to identify the key and is available when
verifying a signature.
SSH has no concept of trust levels like gpg does. To be able to differentiate
between valid signatures and trusted signatures the trust level of a signature
verification is set to fully
when the public key is present in the allowedSignersFile
.
Otherwise the trust level is undefined
and git verify-commit/tag will fail.
This file can be set to a location outside of the repository and every developer
maintains their own trust store. A central repository server could generate this
file automatically from ssh keys with push access to verify the code against.
In a corporate setting this file is probably generated at a global location
from automation that already handles developer ssh keys.
A repository that only allows signed commits can store the file
in the repository itself using a path relative to the top-level of the working tree.
This way only committers with an already valid key can add or change keys in the keyring.
Using a SSH CA key with the cert-authority option
(see ssh-keygen(1)
"CERTIFICATES") is also valid.
gpg.ssh.revocationFile
Either a SSH KRL or a list of revoked public keys (without the principal prefix).
See ssh-keygen(1)
for details.
If a public key is found in this file then it will always be treated
as having trust level "never" and signatures will show as invalid.
随着Git 2.35 (Q1 2022),扩展使用SSH密钥对对象进行签名,并学会在验证时注意密钥有效时间范围。
参见 commit 50992f9, commit 122842f, commit dd3aa41, commit 4bbf378, commit 6393c95, commit 30770aa, commit 0276943, commit cafd345, commit 5a2c1c0 (09 Dec 2021) by Fabian Stelzer (FStelzer
)。
(由 Junio C Hamano -- gitster
-- in commit d2f0b72 合并,2021 年 12 月 21 日)
ssh signing
: make verify-commit consider key lifetime
Signed-off-by: Fabian Stelzer
If valid-before/after dates are configured for this signatures key in the allowedSigners
file then the verification should check if the key was valid at the time the commit was made.
This allows for graceful key rollover and revoking keys without invalidating all previous commits.
This feature needs openssh > 8.8.
Older ssh-keygen versions will simply ignore this flag and use the current time.
Strictly speaking this feature is available in 8.7, but since 8.7 has a bug that makes it unusable in another needed call we require 8.8.
Timestamp information is present on most invocations of check_signature
.
However signer ident is not.
We will need the signer email / name to be able to implement "Trust on first use" functionality later.
Since the payload contains all necessary information we can parse it from there.
The caller only needs to provide us some info about the payload by setting payload_type
in the signature_check
struct.
- Add
payload_type
field & enum and payload_timestamp
to struct `signature_check
- Populate the timestamp when not already set if we know about the payload type
- Pass
-Overify-time={payload_timestamp}
in the users timezone to all ssh-keygen verification calls
- Set the payload type when verifying commits
- Add tests for expired, not yet valid and keys having a commit date outside of key validity as well as within
git config
现在包含在其 man page 中:
Since OpensSSH 8.8 this file allows specifying a key lifetime using valid-after &
valid-before options.
Git will mark signatures as valid if the signing key was
valid at the time of the signatures creation.
This allows users to change a
signing key without invalidating all previously made signatures.
并且,仍然使用 Git 2.35(2022 年第一季度),使用 ssh 密钥的加密签名可以通过使用“key::
”前缀机制
(例如“key::ecdsa-sha2-nistp256
”)。
参见commit 3b4b5a7, commit 350a251 (19 Nov 2021) by Fabian Stelzer (FStelzer
)。
(由 Junio C Hamano -- gitster
-- in commit ee1dc49 合并,2021 年 12 月 21 日)
ssh signing
: support non ssh-* keytypes
Signed-off-by: Fabian Stelzer
The user.signingKey
config for ssh signing supports either a path to a file containing the key or for the sake of convenience a literal string with the ssh public key.
To differentiate between those two cases we check if the first few characters contain "ssh-
" which is unlikely to be the start of a path.
ssh supports other key types which are not prefixed with "ssh-
" and will currently be treated as a file path and therefore fail to load.
To remedy this we move the prefix check into its own function and introduce the prefix key::
for literal ssh keys.
This way we don't need to add new key types when they become available.
The existing ssh-
prefix is retained for compatibility with current user configs but removed from the official documentation to discourage its use.
git config
现在包含在其 man page 中:
If gpg.format
is set to ssh
this can contain the path to either
your private ssh key or the public key when ssh-agent is used.
Alternatively it can contain a public key prefixed with key::
directly (e.g.: "key::ssh-rsa XXXXXX identifier
").
The private key
needs to be available via ssh-agent.
If not set git will call
gpg.ssh.defaultKeyCommand
(e.g.: "ssh-add -L
") and try to use the
first key available.
For backward compatibility, a raw key which
begins with "ssh-
", such as "ssh-rsa XXXXXX identifier
", is treated
as "key::ssh-rsa XXXXXX identifier
", but this form is deprecated;
use the key::
form instead.
"git merge $signed_tag
"(man) 开始意外地从它使用的默认合并消息中删除标记消息,该消息已在 Git 2.35(2022 年第一季度)中得到纠正。
参见commit c39fc06 (10 Jan 2022) by Taylor Blau (ttaylorr
)。
(由 Junio C Hamano -- gitster
-- in commit cde28af 合并,2022 年 1 月 12 日)
fmt-merge-msg
: prevent use-after-free with signed tags
Reported-by: Linus Torvalds
Signed-off-by: Taylor Blau
When merging a signed tag, fmt_merge_msg_sigs()
is responsible for populating the body of the merge message with the names of the signed tags, their signatures, and the validity of those signatures.
In 0276943 ("ssh signing: use sigc struct to pass payload", 2021-12-09, Git v2.35.0-rc0 -- merge listed in batch #4), check_signature()
was taught to pass the object payload via the sigc struct instead of passing the payload buffer separately.
In effect, 0276943 causes buf
, and sigc.payload
to point at the same region in memory.
This causes a problem for fmt_tag_signature()
, which wants to read from this location, since it is freed beforehand by signature_check_clear()
(which frees it via sigc's payload
member).
That makes the subsequent use in fmt_tag_signature()
a use-after-free.
As a result, merge messages did not contain the body of any signed tags.
Luckily, they tend not to contain garbage, either, since the result of strstr()-ing the object buffer in fmt_tag_signature()
is guarded:
const char *tag_body = strstr(buf, "\n\n");
if (tag_body) {
tag_body += 2;
strbuf_add(tagbuf, tag_body, buf + len - tag_body);
}
Resolve this by waiting to call signature_check_clear()
until after its contents can be safely discarded.
Harden ourselves against any future regressions in this area by making sure we can find signed tag messages in the output of fmt-merge-msg, too.
原始答案(2017 年):第一个在 Git 中签署 anything 的想法在 commit ec4465a, Git v0.99, Apr. 2005 中被引用(几乎从一开始)
/**
* A signature file has a very simple fixed format: three lines
* of "object <sha1>" + "type <typename>" + "tag <tagname>",
* followed by some free-form signature that git itself doesn't
* care about, but that can be verified with gpg or similar.
**/
所以你的问题有问题。
第一个签名提交使用了 gpg,但也可以使用其他任何东西 (commit 65f0d0e):
#!/bin/sh
object=${2:-$(cat .git/HEAD)}
type=$(cat-file -t $object) || exit 1
( echo -e "object $object\ntype $type\ntag \n"; cat ) > .tmp-tag
rm -f .tmp-tag.asc
gpg -bsa .tmp-tag && cat .tmp-tag.asc >> .tmp-tag
git-mktag < .tmp-tag
#rm .tmp-tag .tmp-tag.sig
从技术上讲,您可以使用 gpg in place of ssh。不过,我还没有经常看到相反的情况。
但是你可以使用 an ssh key-pair be used with PGP/GPG.
这意味着第一个验证脚本可能仍然有效(commit f336e71)...除了它需要 PGP 注释:
#!/bin/sh
GIT_DIR=${GIT_DIR:-.git}
tag=
[ -f "$GIT_DIR/refs/tags/$tag" ] && tag=$(cat "$GIT_DIR/refs/tags/$tag")
git-cat-file tag $tag > .tmp-vtag || exit 1
cat .tmp-vtag | sed '/-----BEGIN PGP/Q' | gpg --verify .tmp-vtag -
rm -f .tmp-vtag
那么,“为什么 git 使用 GPG 密钥而不是使用 SSH 密钥进行签名?”:这就是 GPG 的目的,而不是 SSH,which cannot do with openssh alone (it needs openssl).
by torek,理论上可以用SSH,就是不方便
In addition, PGP has extra features (not that Git uses them directly—Git itself is just invokes some external software—but things like key revocation are useful in these contexts).
一个可能的原因是并非每个使用 git 的人都在使用 ssh。
您可以创建一个 git 存储库并且永远不会离开您的本地磁盘。您可以使用 git 协议,或 http,或 https,或网络文件系统... none 这些东西涉及 ssh,但您仍然可以签署提交,因为这独立于任何网络传输或其他 push/pull 分享您的提交。
你不应该使用 ssh
签署提交的原因是密码学的常见规则之一:你不应该在不同的 applications/use 情况下使用相同的密钥。
在 SSH 中,您使用密钥进行身份验证,但这与签署您的提交有所不同。为此,GPG 更适合,因为它已被广泛用于签署电子邮件、文件等。
FWIW,允许使用 SSH 密钥进行签名(和验证)的工作正在进行中:https://lore.kernel.org/git/pull.1041.git.git.1625559593910.gitgitgadget@gmail.com/
这可能在有限的(例如公司)上下文中很有价值,在这些上下文中,git 目前是 唯一 处理 GPG 的理由,而坚持使用 SSH 可以节省用户的一些密钥管理和软件管理开销...
SSH 和 GPG 非对称密钥之间的区别是什么?为什么 git 支持使用 GPG 签名而不是使用 SSH 代理?
2021 年更新:
OpenSSH 8.2+ 可用(例如打包在 Git For Windows 2.33.1), and "it is now possible to sign arbitrary data with your SSH keys" (Andrew Ayer 中),包括 Git.
中的提交Andrew 指向 git/git
PR 1041 "ssh signing: Add commit & tag signing/verification via SSH keys using ssh-keygen", now with Git 2.34(2021 年 11 月)
ssh
”
set
gpg.format = ssh
anduser.signingkey
to a ssh public key string (like from an authorized_keys file) and commits/tags can be signed using the private key from your ssh-agent.
安德鲁补充道:
Always be wary of repurposing cryptographic keys for a different protocol. If not done carefully, there's a risk of cross-protocol attacks.
For example, if the structure of the messages signed by Git is similar to the structure of SSH protocol messages, an attacker might be able to forge Git artifacts by misappropriating the signature from an SSH transcript.
Fortunately, the structure of SSH protocol messages and the structure of messages signed by ssh-keygen are dissimilar enough that there is no risk of confusion.
来自:
Git 2.34(2021 年第 4 季度):使用 ssh public 加密进行对象和推送证书签名。
参见 commit 1bfb57f, commit f265f2d, commit 3326a78, commit facca53, commit 4838f62, commit fd9e226, commit 29b3157, commit 64625c7, commit b5726a5 (10 Sep 2021) by Fabian Stelzer (FStelzer
)。
(由 Junio C Hamano -- gitster
-- in commit 18c6653 合并,2021 年 10 月 25 日)
ssh signing
: verify signatures using ssh-keygenSigned-off-by: Fabian Stelzer
To verify a ssh signature we first call
ssh-keygen -Y find-principal
to look up the signing principal by their public key from theallowedSignersFile
.
If the key is found then we do a verify.
Otherwise we only validate the signature but can not verify the signers identity.Verification uses the
gpg.ssh.allowedSignersFile
(seessh-keygen(1)
"ALLOWED SIGNERS") which contains valid public keys and a principal (usuallyuser@domain
).
Depending on the environment this file can be managed by the individual developer or for example generated by the central repository server from known ssh keys with push access.
This file is usually stored outside the repository, but if the repository only allows signed commits/pushes, the user might choose to store it in the repository.To revoke a key put the public key without the principal prefix into
gpg.ssh.revocationKeyring
or generate a KRL (seessh-keygen(1)
"KEY REVOCATION LISTS").
The same considerations about who to trust for verification as with theallowedSignersFile
apply.Using SSH CA Keys with these files is also possible.
Add "cert-authority
" as key option between the principal and the key to mark it as a CA and all keys signed by it as valid for this CA.
See "CERTIFICATES" inssh-keygen(1)
.
git config
现在包含在其 man page 中:
gpg.ssh.allowedSignersFile
A file containing ssh public keys which you are willing to trust. The file consists of one or more lines of principals followed by an ssh public key.
e.g.:user1@example.com,user2@example.com ssh-rsa AAAAX1...
Seessh-keygen(1)
"ALLOWED SIGNERS" for details.
The principal is only used to identify the key and is available when verifying a signature.SSH has no concept of trust levels like gpg does. To be able to differentiate between valid signatures and trusted signatures the trust level of a signature verification is set to
fully
when the public key is present in theallowedSignersFile
.
Otherwise the trust level isundefined
and git verify-commit/tag will fail.This file can be set to a location outside of the repository and every developer maintains their own trust store. A central repository server could generate this file automatically from ssh keys with push access to verify the code against.
In a corporate setting this file is probably generated at a global location from automation that already handles developer ssh keys.A repository that only allows signed commits can store the file in the repository itself using a path relative to the top-level of the working tree. This way only committers with an already valid key can add or change keys in the keyring.
Using a SSH CA key with the cert-authority option (see
ssh-keygen(1)
"CERTIFICATES") is also valid.
gpg.ssh.revocationFile
Either a SSH KRL or a list of revoked public keys (without the principal prefix).
Seessh-keygen(1)
for details.
If a public key is found in this file then it will always be treated as having trust level "never" and signatures will show as invalid.
随着Git 2.35 (Q1 2022),扩展使用SSH密钥对对象进行签名,并学会在验证时注意密钥有效时间范围。
参见 commit 50992f9, commit 122842f, commit dd3aa41, commit 4bbf378, commit 6393c95, commit 30770aa, commit 0276943, commit cafd345, commit 5a2c1c0 (09 Dec 2021) by Fabian Stelzer (FStelzer
)。
(由 Junio C Hamano -- gitster
-- in commit d2f0b72 合并,2021 年 12 月 21 日)
ssh signing
: make verify-commit consider key lifetimeSigned-off-by: Fabian Stelzer
If valid-before/after dates are configured for this signatures key in the
allowedSigners
file then the verification should check if the key was valid at the time the commit was made.
This allows for graceful key rollover and revoking keys without invalidating all previous commits.
This feature needs openssh > 8.8.
Older ssh-keygen versions will simply ignore this flag and use the current time.
Strictly speaking this feature is available in 8.7, but since 8.7 has a bug that makes it unusable in another needed call we require 8.8.Timestamp information is present on most invocations of
check_signature
.
However signer ident is not.
We will need the signer email / name to be able to implement "Trust on first use" functionality later.
Since the payload contains all necessary information we can parse it from there.
The caller only needs to provide us some info about the payload by settingpayload_type
in thesignature_check
struct.
- Add
payload_type
field & enum andpayload_timestamp
to struct `signature_check- Populate the timestamp when not already set if we know about the payload type
- Pass
-Overify-time={payload_timestamp}
in the users timezone to all ssh-keygen verification calls- Set the payload type when verifying commits
- Add tests for expired, not yet valid and keys having a commit date outside of key validity as well as within
git config
现在包含在其 man page 中:
Since OpensSSH 8.8 this file allows specifying a key lifetime using valid-after & valid-before options.
Git will mark signatures as valid if the signing key was valid at the time of the signatures creation.
This allows users to change a signing key without invalidating all previously made signatures.
并且,仍然使用 Git 2.35(2022 年第一季度),使用 ssh 密钥的加密签名可以通过使用“key::
”前缀机制
(例如“key::ecdsa-sha2-nistp256
”)。
参见commit 3b4b5a7, commit 350a251 (19 Nov 2021) by Fabian Stelzer (FStelzer
)。
(由 Junio C Hamano -- gitster
-- in commit ee1dc49 合并,2021 年 12 月 21 日)
ssh signing
: support non ssh-* keytypesSigned-off-by: Fabian Stelzer
The
user.signingKey
config for ssh signing supports either a path to a file containing the key or for the sake of convenience a literal string with the ssh public key.To differentiate between those two cases we check if the first few characters contain "
ssh-
" which is unlikely to be the start of a path.
ssh supports other key types which are not prefixed with "ssh-
" and will currently be treated as a file path and therefore fail to load.
To remedy this we move the prefix check into its own function and introduce the prefixkey::
for literal ssh keys.
This way we don't need to add new key types when they become available.
The existingssh-
prefix is retained for compatibility with current user configs but removed from the official documentation to discourage its use.
git config
现在包含在其 man page 中:
If
gpg.format
is set tossh
this can contain the path to either your private ssh key or the public key when ssh-agent is used. Alternatively it can contain a public key prefixed withkey::
directly (e.g.: "key::ssh-rsa XXXXXX identifier
").The private key needs to be available via ssh-agent.
If not set git will callgpg.ssh.defaultKeyCommand
(e.g.: "ssh-add -L
") and try to use the first key available.For backward compatibility, a raw key which begins with "
ssh-
", such as "ssh-rsa XXXXXX identifier
", is treated as "key::ssh-rsa XXXXXX identifier
", but this form is deprecated; use thekey::
form instead.
"git merge $signed_tag
"(man) 开始意外地从它使用的默认合并消息中删除标记消息,该消息已在 Git 2.35(2022 年第一季度)中得到纠正。
参见commit c39fc06 (10 Jan 2022) by Taylor Blau (ttaylorr
)。
(由 Junio C Hamano -- gitster
-- in commit cde28af 合并,2022 年 1 月 12 日)
fmt-merge-msg
: prevent use-after-free with signed tagsReported-by: Linus Torvalds
Signed-off-by: Taylor Blau
When merging a signed tag,
fmt_merge_msg_sigs()
is responsible for populating the body of the merge message with the names of the signed tags, their signatures, and the validity of those signatures.In 0276943 ("ssh signing: use sigc struct to pass payload", 2021-12-09, Git v2.35.0-rc0 -- merge listed in batch #4),
check_signature()
was taught to pass the object payload via the sigc struct instead of passing the payload buffer separately.In effect, 0276943 causes
buf
, andsigc.payload
to point at the same region in memory.
This causes a problem forfmt_tag_signature()
, which wants to read from this location, since it is freed beforehand bysignature_check_clear()
(which frees it via sigc'spayload
member).That makes the subsequent use in
fmt_tag_signature()
a use-after-free.As a result, merge messages did not contain the body of any signed tags.
Luckily, they tend not to contain garbage, either, since the result of strstr()-ing the object buffer infmt_tag_signature()
is guarded:const char *tag_body = strstr(buf, "\n\n"); if (tag_body) { tag_body += 2; strbuf_add(tagbuf, tag_body, buf + len - tag_body); }
Resolve this by waiting to call
signature_check_clear()
until after its contents can be safely discarded.
Harden ourselves against any future regressions in this area by making sure we can find signed tag messages in the output of fmt-merge-msg, too.
原始答案(2017 年):第一个在 Git 中签署 anything 的想法在 commit ec4465a, Git v0.99, Apr. 2005 中被引用(几乎从一开始)
/**
* A signature file has a very simple fixed format: three lines
* of "object <sha1>" + "type <typename>" + "tag <tagname>",
* followed by some free-form signature that git itself doesn't
* care about, but that can be verified with gpg or similar.
**/
所以你的问题有问题。
第一个签名提交使用了 gpg,但也可以使用其他任何东西 (commit 65f0d0e):
#!/bin/sh
object=${2:-$(cat .git/HEAD)}
type=$(cat-file -t $object) || exit 1
( echo -e "object $object\ntype $type\ntag \n"; cat ) > .tmp-tag
rm -f .tmp-tag.asc
gpg -bsa .tmp-tag && cat .tmp-tag.asc >> .tmp-tag
git-mktag < .tmp-tag
#rm .tmp-tag .tmp-tag.sig
从技术上讲,您可以使用 gpg in place of ssh。不过,我还没有经常看到相反的情况。
但是你可以使用 an ssh key-pair be used with PGP/GPG.
这意味着第一个验证脚本可能仍然有效(commit f336e71)...除了它需要 PGP 注释:
#!/bin/sh
GIT_DIR=${GIT_DIR:-.git}
tag=
[ -f "$GIT_DIR/refs/tags/$tag" ] && tag=$(cat "$GIT_DIR/refs/tags/$tag")
git-cat-file tag $tag > .tmp-vtag || exit 1
cat .tmp-vtag | sed '/-----BEGIN PGP/Q' | gpg --verify .tmp-vtag -
rm -f .tmp-vtag
那么,“为什么 git 使用 GPG 密钥而不是使用 SSH 密钥进行签名?”:这就是 GPG 的目的,而不是 SSH,which cannot do with openssh alone (it needs openssl).
In addition, PGP has extra features (not that Git uses them directly—Git itself is just invokes some external software—but things like key revocation are useful in these contexts).
一个可能的原因是并非每个使用 git 的人都在使用 ssh。
您可以创建一个 git 存储库并且永远不会离开您的本地磁盘。您可以使用 git 协议,或 http,或 https,或网络文件系统... none 这些东西涉及 ssh,但您仍然可以签署提交,因为这独立于任何网络传输或其他 push/pull 分享您的提交。
你不应该使用 ssh
签署提交的原因是密码学的常见规则之一:你不应该在不同的 applications/use 情况下使用相同的密钥。
在 SSH 中,您使用密钥进行身份验证,但这与签署您的提交有所不同。为此,GPG 更适合,因为它已被广泛用于签署电子邮件、文件等。
FWIW,允许使用 SSH 密钥进行签名(和验证)的工作正在进行中:https://lore.kernel.org/git/pull.1041.git.git.1625559593910.gitgitgadget@gmail.com/
这可能在有限的(例如公司)上下文中很有价值,在这些上下文中,git 目前是 唯一 处理 GPG 的理由,而坚持使用 SSH 可以节省用户的一些密钥管理和软件管理开销...