Git基础11 — 对提交进行签名验证

前言

在前面的文章中,我们知道 Git 的配置文件有三个:

  1. 系统配置文件 – 针对任意登录操作系统的用户都生效。在 Windows 中,这里的配置修改对应于 Git 安装目录下面的 /etc/gitconfig 文件中的内容;在 GNU/Linux 中,若是从存储库中安装的 Git, 则配置修改对应于 /etc/gitconfig 文件中的内容
  2. 全局配置文件 – 针对当前登录操作系统的用户生效。这里的配置修改对应于当前用户家目录(也称主目录)下的 .gitconfig 文件中的内容
  3. 项目配置文件 – 仅针对某个 git 存储库生效。这里的配置修改对应于当前项目目录的 .git/config 文件中的内容

Git 读取配置的先后顺序:系统配置文件 —> 全局配置文件 —-> 项目配置文件,若某些设置项重叠,则以 Git 最后读取到的设置项为准。

初始配置时,我们只配置了用户名与邮箱:

Shell > git config --global user.name "xxxxxxxxx"

Shell > git config --global user.email "[email protected]"

Git 这一简单的身份验证对 Github 而言是很不安全的,别人可以几乎零成本地冒充身份,所有为了保证您每次的提交操作都是本人提交而非其他人伪造的,在 Git 当中使用了「非对称加密」来完成提交的验证。验证成功后,您每次提交后对会有一个 Verified 单词,就像这样:

对称加密

术语:

  • 明文:未被加密的原始数据,没有加密的字符串
  • 密文:原始数据被某种加密算法加密之后的文字或字符串
  • 密钥:密码中的一种参数,用在明文转密文或密文转明文。可划分为对称密钥与非对称密钥,对应的是对称加密与非对称加密。

Q:什么是对称加密?

信息的发送方和接收方使用 同一个密钥 去加密和解密数据。

加密过程:明文 + 加密算法 + 私钥 => 密文

解密过程:密文 + 解密算法 + 私钥 => 明文

如下图所示:

私钥:对称加密中用到的密钥被称为私钥,即私有的密钥,不允许泄露。

「对称」指的是加密过程中的私钥与解密过程中的私钥使用的是 同一个密钥

非对称加密

既然被称为非对称加密,由前文可知,加密过程中的密钥与解密过程中的密钥肯定是不同的。

非对称加密使用一对密钥,即「公钥」(publickey)和「私钥」(privatekey),其特点如下:

  • 公钥和私钥成对出现
  • 公开的密钥叫公钥,只有自己知道的叫私钥
  • 用公钥加密的数据只有对应的私钥可以解
  • 用私钥加密的数据只有对应的公钥可以解
  • 如果可以用公钥解密,则必然是对应的私钥加密的
  • 如果可以用私钥解密,则必然是对应的公钥加密的

加密过程:明文 + 加密算法 + 公钥 => 密文

解密过程:密文 + 解密算法 + 私钥 => 明文

Windows 当中的配置

这里以 GPG (一个非对称加密的软件)为例来说明:

  1. 前提条件

    您的 Github 账号必须是通过了验证的邮箱 —— https://github.com/settings/emails

  2. 使用 Windows 的 Git bash 并查看其版本

    Windows 的 Git bash 默认已经包含了 GPG 工具,所以您的 GPG 不需要额外的进行安装。

    Bash > gpg --version
    gpg (GnuPG) 2.4.5-unknown
    libgcrypt 1.9.4-unknown
    Copyright (C) 2024 g10 Code GmbH
    License GNU GPL-3.0-or-later 
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    
    Home: /c/Users/litia/.gnupg
    Supported algorithms:
    Pubkey: RSA, ELG, DSA, ECDH, ECDSA, EDDSA
    Cipher: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH,
          CAMELLIA128, CAMELLIA192, CAMELLIA256
    Hash: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224
    Compression: Uncompressed, ZIP, ZLIB, BZIP2

    Github 支持的密钥算法有:

    • RSA
    • ElGamal
    • DSA
    • ECDH
    • ECDSA
    • EdDSA
  3. 检查现有的 GPG 密钥对

    # 在生成 GPG 密钥对之前,您可以检查是否有任何现有的 GPG 密钥对,若没有,则执行「生成新的 GPG 密钥对」这一步
    Bash > gpg --list-secret-keys --keyid-format=long
    /c/Users/litia/.gnupg/pubring.kbx
    ---------------------------------
    sec   rsa4096/4D6FE61DACDB01E6 2023-11-02 [SC] [expires: 2025-11-02]
      7D87FC5C3FC33F78EA1058E14D6FE61DACDB01E6
    uid                 [ultimate] xxxx 

    若存在现有的 GPG 密钥对,则 gpg --list-secret-keys --keyid-format=long 的输出有几个部分:

    1. 密钥对(私钥与公钥)在本地的路径位置
    2. sec 表示是私钥;rsa 4096 表示私钥的算法是 RSA 以及 4096 长度;4D6FE61DACDB01E6 表示私钥 ID(也可以指公钥 ID);SC 表示用途标志(Signing/Certification,签名和认证);「expires: 2025-11-02」表示密钥对的过期时间
    3. 7D87FC5C3FC33F78EA1058E14D6FE61DACDB01E6 表示完整的 40 位密钥对指纹
    4. uid 表示与用户关联的信息
    # 如果存在现有的 GPG 密钥对,且您希望使用它来对提交进行签名,您可以使用以下命令将二进制的公钥(私钥)以 ASCII 格式导出。在本示例中,GPG 私钥(公钥)的 ID 为 4D6FE61DACDB01E6,您可以替换为您的 GPG 私钥 ID(公钥 ID)
    ## 接着,来到 「将 GPG 公钥或私钥添加到您的 Github 账户」这一步
    Bash > gpg --armor --export 4D6FE61DACDB01E6
  4. 生成新的 GPG 密钥对

    这将会有一个应答交互的过程,分别是:选择密钥对类型、密钥对长度、过期时间、用户名、邮箱、key的安全密码。

    Bash > gpg --full-generate-key
    Please select what kind of key you want:
      (1) RSA and RSA (default) 
      (2) DSA and Elgamal       
      (3) DSA (sign only)       
      (4) RSA (sign only)       
     (14) Existing key from card
    Your selection? 1
    RSA keys may be between 1024 and 4096 bits long.
    What keysize do you want? (3072) 4096
    Requested keysize is 4096 bits
    Please specify how long the key should be valid.
            0 = key does not expire
           = key expires in n days
         w = key expires in n weeks
         m = key expires in n months
         y = key expires in n years
    Key is valid for? (0) 30
    Key expires at 2023年06月28日 13:52:13    
    Is this correct? (y/N) y
    
    GnuPG needs to construct a user ID to identify your key.
    
    Real name: xxxx
    Email address: [email protected]
    Comment: 
    You selected this USER-ID:
       xxxx 
    
    Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    We need to generate a lot of random bytes. It is a good idea to perform
    some other action (type on the keyboard, move the mouse, utilize the
    disks) during the prime generation; this gives the random number
    generator a better chance to gain enough entropy.
    gpg: key 6F8508D561C608EC marked as ultimately trusted
    gpg: directory '/c/Users/litia/.gnupg/openpgp-revocs.d' created
    gpg: revocation certificate stored as '/c/Users/litia/.gnupg/openpgp-revocs.d/D1EDFAA78BB6FD04B701AC056F8508D561C608EC.rev'
    public and secret key created and signed.
    
    pub   rsa4096 2023-05-29 [SC] [expires: 2023-06-28]
         D1EDFAA78BB6FD04B701AC056F8508D561C608EC
    uid                      xxxx 
    sub   rsa4096 2023-05-29 [E] [expires: 2023-06-28]
    
    # 再次列出您的私钥信息
    Bash > gpg --list-secret-keys --keyid-format=long
    /c/Users/litia/.gnupg/pubring.kbx
    ---------------------------------
    sec   rsa4096/6F8508D561C608EC 2023-05-29 [SC] [expires: 2023-06-28]   
         D1EDFAA78BB6FD04B701AC056F8508D561C608EC
    uid                 [ultimate] tianci li 
    ssb   rsa4096/BF049206D8276597 2023-05-29 [E] [expires: 2023-06-28]    
    
    # 将二进制的私钥(公钥)以 ASCII 格式导出。复制以 -----BEGIN PGP PUBLIC KEY BLOCK----- 开头并以 -----END PGP PUBLIC KEY BLOCK----- 结尾的 GPG 公钥。
    Bash > gpg --armor --export 6F8508D561C608EC
    -----BEGIN PGP PUBLIC KEY BLOCK-----
    
    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
    aHhb+aLATiyegnF3gca4ww==
    =B39W
    -----END PGP PUBLIC KEY BLOCK-----
  5. 将 GPG 公钥或私钥添加到您的 Github 账户

  6. 在本地 git 中配置 GPG 签名

    # 将 私钥 ID (公钥 ID)添加到您的 git 设置中
    Bash > git config --global user.signingkey 6F8508D561C608EC
    
    # (可选)默认对所有的提交进行签名
    Bash > git config --global commit.gpgsign true
  7. 验证

    当您使用 git commit 命令进行提交时,需要您输入 key 的安全密码以便对提交进行签名。推送到远程库则可以看到实际的效果。

GPG 密钥的其他问题

Q:我的 GPG 密钥对过期了,应该怎么办?

可使用 gpg --edit-key 命令更新已有的 GPG 密钥对。

Bash > gpg --edit-key <私钥 ID 或 公钥 ID>

gpg> expire
...

gpg> save

Q:我可以删除已有的 GPG 密钥对吗?

可以。需要注意!您需要先删除私钥再删除公钥。使用以下命令:

Bash > gpg --delete-secret-keys  <私钥 ID 或公钥 ID>

Bash > gpg --delete-key <公钥 ID 或公钥 ID>

直到 gpg --list-keysgpg --list-secret-keys 这两条命令无任何输出本文。

若无特殊情况,则私钥 ID 与 公钥 ID 是相同的,因为都是以二进制格式存放在一个文件中,比如上面示例中的 /c/Users/litia/.gnupg/pubring.kbx

GPG 的原理

PGP、OpenPGP、GPG之间的关系:

  • GPG:GPG是 GNU Privacy Guard 的缩写,它是 OpenPGP 加密标准的一个实现,同时也是 PGP 的开源实现。
  • OpenPGP:一种协议标准
  • PGP:由 Phil Zimmermann 开发,其最终被赛门铁克收购,是一个商业软件,需要付费。

GPG 是符合 OpenPGP 标准的,因此说 OpenPGP 的原理,就等同于 GPG 的原理。加密解密如下图所示,发送方随机生成一个 key,并用随机 key 加密数据,最后通过非对称算法(图中使用的是 RSA)并用接收方的公钥加密前者,最终得到密文(encrypted message)。当接收者拿到密文时,使用自己的私钥进行解密,拿到随机 key 解密加密的数据,得到原始的数据。

如果你细心发现的话, https 的加密解密也是差不多的理念:

OpenPGP 除了可以 加密/解密 数据外,还拥有数字签名的功能。数字签名和现实世界的功能是类似的,即:

  • 验证发送者的身份 – 确保发送者是其本人。
  • 完整性 – 文件/数据/邮件 在传输过程中未被篡改。
  • 不可否认性 – 一旦发送者发送了 文件/数据/邮件,发送者不可否认。

发送者先通过加密散列函数获取数据的哈希,然后使用发送者的私钥加密哈希,最终得到数字签名的数据。接收者使用发送者的公钥解密数字签名的数据并得到一个哈希,并与自己计算的数据的哈希值做对比,相同则表示数字签名有效且数据完整。在对 文件/邮件/数据 签名的过程中,为什么必须使用签名者的私钥?因为签名者是唯一具有私钥的人,只有它签的名才能成为信任的源头,但公钥则不行。

Avatar photo

关于 陸風睿

GNU/Linux 从业者、开源爱好者、技术钻研者,撰写文档既是兴趣也是工作内容之一。Q - "281957576";WeChat - "jiulongxiaotianci",Github - https://github.com/jimcat8
用一杯咖啡支持我们,我们的每一篇[文档]都经过实际操作和精心打磨,而不是简单地从网上复制粘贴。期间投入了大量心血,只为能够真正帮助到您。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇