使用 Git 关联远程仓库通常可以使用 HTTP 协议或者 SSH 协议,在使用上 SSH 只需要一次配置,之后提交操作都不需要进行用户密码验证;但是 HTTP 方式每次 Push 操作都需要验证用户名和密码。
当然,HTTP 方式更方便开源,匿名用户可以随意进行克隆和代码阅读;在个人项目使用的时候则需要反复进行 Push 操作, 可以通过配置 SSH 实现快捷的代码提交。
01 为指定账户创建密钥
1️⃣ 首先需要设置绑定密钥的 Git 用户名和邮箱地址,在终端运行如下命令
git config --global user.name 'yourname'
git config --global user.email 'youremail@example.com'
如果在此之前已经设置过了,可以直接获取即可。
git config --global user.email
2️⃣ 然后,使用 ssh-keygen
命令为上述账号创建密钥,其中命令的参数选项中 -t
用于指定密钥类型;-C
用于设置注释文字,比如邮箱;还有 -f
用于指定密钥文件存储文件名。
ssh-keygen -t rsa -C "youremail@example.com"
如果执行上面命令报错,需要检查你的电脑是否安装了 openssh
首先,以管理员身份运行 Windows powershell
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'
# 会得到如下内容
Name : OpenSSH.Client~~~~0.0.1.0
State : Installed
Name : OpenSSH.Server~~~~0.0.1.0
State : NotPresent
根据你的 Client 和 Server 的状态 State 执行下面的命令安装对应组件
# Install the OpenSSH Client
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0
# Install the OpenSSH Server
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
安装完成之后,在终端中执行上面的 ssh-keygen
命令可以得到如下图所示的内容
- 如果命令行中省略
-f
参数会提醒输入一个文件名来保存密钥Enter file in which to save the key...
,没有特殊需求的话这里可以直接按Enter
跳过使用默认文件名。- 接着又会提示输入两次密码
passphrase
,这个密码是进行 Git Push 操作的时候要输入的密码,Github 账号无关。如果没有特殊的安全性需要这里也可以直接按Enter
跳过,不设置密码,这样可以在 Push 操作的时候不输入密码直接提交。
命令行执行完成之后,如果你也获得了上图中相似的信息那么就说明 SSH Key 已经创建成功了,红色方框中的路径地址就是你的密钥保存的文件位置。
02 将密钥添加到本地主机的 ssh-agent 服务
生产了密钥之后,本地主机需要将私钥添加到 ssh-agent 服务中。
1️⃣ 首先,需要启动 ssh-agent 服务。在 Win10 中可以在管理员权限下通过 Set-Service -StartupType Automatic ssh-agent
将 ssh-agent 服务的启动类型设为自启,然后使用 Start-Service ssh-agent
命令启动当前会话下的 ssh-agent 服务。
Set-Service -StartupType Automatic ssh-agent
Start-Service ssh-agent
Get-Service ssh-agent # 查看服务是否启动成功
2️⃣ 然后使用 ssh-add
命令将新建的密钥添加到 ssh-agent 服务中
ssh-add /C/Users/regul/.ssh/id_rsa # 修改为你的密钥文件路径
下图中添加的密钥已经在当前目录下,所以直接使用了相对路径。
03 将公钥添加到 Github 账户
到此为止,本地主机的 SSH 配置已经完成了,最后将公钥添加到 Github 账户中即可。
1️⃣ 首先,拷贝第一步中生成的公钥 id_rsa.pub
中的完整内容,如下图所示
2️⃣ 然后,进入到你的 Github 的设置页面中点击 New SSH key
按钮添加公钥
3️⃣ 最后,在添加 SSH key 的页面中的 Key
栏中输入前面拷贝的公钥,Title 中也可以设置这个新 key 的名称,完成之后点击 Add SSH key
按钮即可
最后的最后,在终端里面输入如下命令,测试一下本地与Github 的 SSH key 配置是否成功
ssh -T git@github.com
显示内容和下图相似,那么恭喜你已经完成了 SSH key 的配置,后面就可以自由的进行 Push 提交操作。(如果配置完成之后还发现需要验证用户名和密码,请检查一下项目的克隆方式是 HTTPS 还是 SSH)
如果已经使用 HTTP 方式克隆了仓库,则执行如下命令需要修改远程仓库地址
git remote set-url origin <url>
04 SSH 协议原理理解
Github SSH Key 的配置已经完成了,接下来一起探究一下为什么 SSH 方式可以免除 HTTP 方式中的用户验证步骤呢 ❓
4.1 对称加密与非对称加密
为了提高安全性,在向远程仓库提交代码的时候需要对提交的内容进行加密,即通过加密算法将明文转换为密文进行安全传输。
加密的方式通常有两种:
- 对称加密:加密解密都是用的是同一个密钥
- 非对称加密:加密解密过程由一对公钥和私钥组成,这对密钥可以进行相互的加密解密。
对称加密的密钥通常是使用通信双方的共享信息生成的,所以其加密解密过程的速度更快,适用于传输大量数据的场景。🙋♂️ 但是对称加密存在一个很大的安全性问题:在通信初始阶段如何安全地将密钥从持有方发送给还未保存密钥的接收方,以及接收方获得密钥后双方如何安全地维护该密钥 ❓
非对称加密就通过密钥对有效解决了这个问题,私钥由生成的一方自己保管,公钥可以发送给任何请求通信的请求方。发送方用收到的公钥对自己的通信内容进行加密,只有接收方可以使用私钥进行解密获取通信内容。👉 非对称加密的私钥不需要暴露在网络中,安全性大大增加,但是加解密的速度比对称密钥慢得多。 👈
但是非对称加密又会引发中间人攻击(Man-in-the-MiddleAttack,MITM) 🧛,这是一种缺乏相互认证导致的攻击,攻击者可以拦截通讯双方的通话并插入新的内容。
如下图所示,在密钥交换阶段攻击者通过拦截客户端和服务端的通信信息并将双方的公钥都保存并替换成攻击者生成的公钥。在通信阶段客户端和服务端都在使用攻击者提供的公钥加密通信信息,这种情况下通信双方的加密通信对于攻击而言就是透明的。
避免中间人攻击的主要方式就是提供认证机制让客户端和服务端都能够验证公钥是否是来自对方的。
HTTPS 中就是使用了数字证书机制来进行公证确认身份,更为简单的方式就是客户端自己亲自把自己的公钥放到服务端上,通过这种方式就能代替第三方验证确定公钥来自该客户端,这就是本文第 03 节中的将公钥添加到 Github 账户中的过程,这样就可以使用 SSH 进行代码提交拉取等 Git 操作。
4.2 SSH 密钥认证
SSH 连接过程中在密钥交换阶段和用户认证阶段两个阶段都使用了非对称加密:
- 密钥交换阶段:客户端和服务端都生成了自己临时的公钥和私钥,用于计算出同一个用于后续加密通信内容的会话密钥。
- 用户认证阶段:利用只有匹配的私钥可以唯一解密公钥加密的内容这一特点,使用客户端的公钥私钥来验证客户端的身份。
SSH 通过密钥认证方式进行用户认证,利用私钥公钥唯一对应的特性实现免密登录,认证步骤如下:
- 客户端自己将本地生成的公钥存放到服务端上,并追加到
authorized_keys
文件中- 服务端接收到客户端的连接请求后,在
authorized_keys
中匹配查找客户端的公钥,并用该公钥对服务端生成的随机数进行加密作为验证信息发送给客户端- 客户端使用自己的私钥对服务端返回信息进行解密,然后对随机数和密钥协商中生成的会话密钥
SessionKey
利用密钥协商过程确定的加密算法生成摘要 Digest1,并发送给服务端- 服务端会也会对生成的随机数和会话密钥SessionKey利用同样的加密算法生成摘要 Digest2。服务端收到客户端的 Digest1 后会与 Digest2 进行验证,如果一致则认证完成
SSH 用户认证除了使用密钥认证还可以通过最基本的密码认证方式进行认证。密码认证是将自己的用户名和密码发送给服务器进行认证,这种方式比较简单,但是每次登录都需要输入用户名和密码。
如果文章对你有帮助,欢迎一键三连 👍 ⭐️ 💬 。如果还能够点击关注,那真的是对我最大的鼓励 🔥🔥🔥 。