GPG: Add a lock to your Git commits

Original link: https://lisz.me/tech/webmaster/gpg.html

foreword

GPG, the full name of GNU Privacy Guard, can also be written as GnuPG. It is a free and open source encryption software, and a substitute for PGP (Pretty Good Privacy), which is not open source and not free. For details, please refer to the reference materials. Since GPG can be used for signature or encryption, it is widely used in file encryption, email encryption, code signing, etc.

Email encryption

Students who have used Gmail may have seen different security information like the one below. The first picture shows that Gmail considers the security level of the message to be the lowest unencrypted level when it is not sent over an SSL connection to the mail server. The second picture is when the mail server is normally sent via SSL connection, and Gmail verifies that the SSL certificate is consistent with the mailing domain and recognizes it as the security level of standard encryption . The third picture is that when we encrypt the email with GPG, Gmail will also receive a signed public key as an attachment.

Unencrypted mail
Normal certified mail
GPG encrypted mail GPG certified mail

It may seem strange here, why is there no difference between GPG-encrypted emails and normal standard encrypted emails except for attachments? In fact, if we want to send a GPG-encrypted email to the other party, we need to encrypt the content of the email with the other party’s GPG public key. When the other party receives the sent GPG-encrypted email, it will decrypt it with its own private key, so as to know the content of the encrypted email. That said, the third image above is not a true GPG encrypted message. The third picture is the email signed by the author with the private key. The recipient can use the public key queried on the keyserver to verify whether the email content really comes from the sender.

code signing

Compared to email encryption, GPG is used for code signing on the opposite side. In code signing, we also use the private key to sign each commit as in the third picture above. The user of the code can verify the content of the code according to the public key published by the author to ensure that the code is from the author himself. The Apple developer certificate and the Google Play developer certificate actually play a role in verifying the authorship of the code.

Git “holes”

Before Git submits a commit, Git will ask us to set username and email (similar to below). But what if we don’t set our own github username and email? In fact, it doesn’t matter, but Github will not count these commits on your head, but on your fake users. If we want to masquerade as the github account of a big industry celebrity to submit code for the project, it seems that there is nothing impossible in theory. In Reference 4, the author tried some examples and found that “as long as you know your email address, you can submit commits in the name of others”. But at the end of the day, this approach is immoral and has no real meaning.

 git config --global user.name "zhonger" git config --global user.email "[email protected]"

Therefore, in order to make the code more credible and ensure that it is submitted by the author himself, code hosting platforms such as Github have supported GPG signing. Because GPG public and private keys are generated by RSA asymmetric encryption, there is no risk of forgery or anti-encoding in theory. Unlike the public key query verification from the GPG key server, code hosting platforms such as Github only trust the GPG public key configured by the author himself in the settings, similar to only trusting the configured SSH public key access code.

practice

Install GPG

GPG is already provided on different platforms, and most of them only require one command to complete the installation.

 # MacOS brew install gpg # Debian, Ubuntu sudo apt install -y gnupg # CentOS sudo yum install -y gnupg # Windows # 推荐使用WinGPG,下载地址为https://scand.com/products/wingpg/ # Archlinux sudo pacman -S gnupg

Verify installation

 ╰─ $ gpg --version gpg ( GnuPG ) 2.3.6 libgcrypt 1.10.1 Copyright ( C ) 2021 Free Software Foundation, Inc. License GNU GPL-3.0-or-later <https://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Home: /Users/zhonger/.gnupg支持的算法:公钥: RSA, ELG, DSA, ECDH, ECDSA, EDDSA密文: IDEA, 3DES, CAST5, BLOWFISH, AES, AES192, AES256, TWOFISH, CAMELLIA128, CAMELLIA192, CAMELLIA256 AEAD: EAX, OCB散列: SHA1, RIPEMD160, SHA256, SHA384, SHA512, SHA224压缩: 不压缩, ZIP, ZLIB, BZIP2

generate key

Once you have verified that the installation was successful, you can use the following command to generate an alpha key. As shown below, we can easily get a pair of GPG keys.

 ╰─ $ gpg --full-generate-key gpg ( GnuPG ) 2.3.6 ; Copyright ( C ) 2021 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law.请选择您要使用的密钥类型: ( 1 ) RSA 和RSA ( 2 ) DSA 和Elgamal ( 3 ) DSA(仅用于签名) ( 4 ) RSA(仅用于签名) ( 9 ) ECC(签名和加密) *默认* ( 10 ) ECC(仅用于签名) (14)卡中现有密钥您的选择是?请选择您想要使用的椭圆曲线: ( 1 ) Curve 25519 *默认* ( 4 ) NIST P-384 ( 6 ) Brainpool P-256您的选择是?请设定这个密钥的有效期限。 0 = 密钥永不过期<n> = 密钥在n 天后过期<n>w = 密钥在n 周后过期<n>m = 密钥在n 月后过期<n>y = 密钥在n 年后过期密钥的有效期限是? ( 0 )密钥永远不会过期这些内容正确吗? ( y/N ) y GnuPG 需要构建用户标识以辨认您的密钥。真实姓名: zhonger电子邮件地址: [email protected]注释: zhonger您选定了此用户标识: “zhonger ( zhonger ) <[email protected]>”更改姓名(N)、注释(C)、电子邮件地址(E)或确定(O)/退出(Q)? O我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数发生器有更好的机会获得足够的熵。 gpg: 警告:服务器'gpg-agent' 比我们的版本更老(2.2.34 < 2.3.6) gpg: 注意: 过时的服务器可能缺少重要的安全修复。 gpg: 注意: 使用“gpgconf --kill all” 来重启他们。我们需要生成大量的随机字节。在质数生成期间做些其他操作(敲打键盘、移动鼠标、读写硬盘之类的)将会是一个不错的主意;这会让随机数发生器有更好的机会获得足够的熵。 gpg: 吊销证书已被存储为'/Users/zhonger/.gnupg/openpgp-revocs.d/612E7E8200528FEC0B8AC3C715F73C3703B9796C.rev'公钥和私钥已经生成并被签名。 pub ed25519 2022-06-01 [ SC] 612E7E8200528FEC0B8AC3C715F73C3703B9796C uid zhonger ( zhonger ) <[email protected]> sub cv25519 2022-06-01 [ E]

Here, the key type, elliptic curve, and key validity period required to be selected in the key generation process are all selected by default (press the Enter key), which can be selected according to personal needs. The following user IDs are based on the individual’s real name (in English), Github email and username (comments), and finally enter a capital letter O to end the setup. After this step, the system will remind you to enter the password for the private key, which usually requires two verification inputs. So far, a pair of GPG keys have been successfully generated.

Github configuration key

After generating the key, we need to add the public key to Github, and try to use the private key to sign and submit the code to verify whether it is successfully verified by Github.

print public key

As shown in the following command, you can query the content of the public key of the key just generated and copy it.

 # 列举本地所有密钥gpg --list-keys # 查询指定id 密钥的公钥内容gpg --armor --export <GPG_KEY_ID》 

List gpg keys
Check public key content

Add GPG public key

Visit https://github.com/settings/gpg/new to add the GPG public key you just copied. The Title here can be named arbitrarily, as long as it does not duplicate the existing Title.

Add public key

Query added public key

Visit https://github.com/settings/keys to see the newly added GPG public key. Here you can see that there is an Unverified after the email address. This is because this mailbox is a fake mailbox that is not bound to a Github account. If the mailbox is verified, there will be no such logo here.

Query public key List all keys

Sign the code and commit

In order not to manually declare the use of a GPG private key for signing every time a commit is submitted, two configuration items are added to the global configuration of git: user.signingkey (signature key ID) and commit.gpgsign (all submissions) signed with GPG).

 git config --global user.signingkey 612E7E8200528FEC0B8AC3C715F73C3703B9796C git config --global commit.gpgsign true

After we set up the global Git configuration, when we execute commit again as usual, a window for entering the private key password will pop up, just enter it normally.

Verify commit signature

Although the above steps have been completed to add a lock to the commit by GPG, it may not be possible to confirm whether the lock exists. There are two ways to verify here: one is by querying your local git, and the other is online via Github. The following are the renderings of using the personal private key (not the example key in this article) to verify the two methods in the daily git project.

 # 本地验证提交签名git log --show-signature 

Verify the signature on local git
Github Verify the signature on github

Other related questions

Question one

What if I want to export private and public keys for backup or migration?

answer

In general, custody of GPG keys is very important. If the private key of the GPG key is lost or stolen, it can be dangerous because someone can use the private key to sign any file or email with your name. So be sure to make a backup before reinstalling the computer, even if you usually need to store the GPG key in a non-local and safe and reliable location. The following commands can implement the export of public and private keys.

 gpg --armor --output gpg.pub --export <GPG_KEY_ID> gpg --armor --output gpg.key --export-secret-keys <GPG_SECRET_KEY>
Question two

How do I revoke a generated or lost GPG key?

answer

When the GPG private key is lost (the loss of the public key does not affect the security, it can be retrieved), we need to delete the corresponding public key in Github, so as to ensure that Github will no longer recognize the code signed by the lost private key. Of course, in order to no longer trust the lost private key signature for other normal emails and files except Github, we need to declare to GPG that the GPG public key is revoked, so as to achieve the purpose of revoking the private key (not to delete the key itself, but to revoke the private key). marked obsolete). The specific operation is shown in the following command.

 # 撤销密钥gpg --output revoke.asc --gen-revoke <GPG_KEY_ID> # 将撤销密钥导入本地钥匙环gpg --import revoke.asc # 搜索GPG 密钥服务器中的密钥gpg --keyserver hkps://keys.openpgp.org --search-keys <GPG_KEY_ID> # 撤销GPG 密钥服务器上的密钥gpg --keyserver hkps://keys.openpgp.org --send-keys <GPG_KEY_ID>

References

This article is reprinted from: https://lisz.me/tech/webmaster/gpg.html
This site is for inclusion only, and the copyright belongs to the original author.

Leave a Comment