Please enable Javascript to view the contents

SSH-key的生成与在Git中的使用

 ·  ☕ 9 分钟

先来了解什么是 SSH 和什么是 SSH key。

简单的说:Secure Shell(SSH)是一种网络协议,用于加密客户端和服务器之间的连接。

SSH

Secure Shell (SSH) 是一个允许两台电脑之间通过安全的连接进行数据交换 的网络协议。通过加密保证了数据的保密性和完整性。SSH 采用公钥加密技术 来验证远程主机,以及(必要时)允许远程主机验证用户。

传统的 FTP、Telnet 是再网络中明文传送数据、用户帐号和密码,很容易受到中间人攻击 。

SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用 SSH 协议 可以有效防止远程管理过程中的信息泄露问题。通过SSH可以对所有传输的数据进行加 密,也能够防止 DNS 欺骗和 IP 欺骗。

      ssh客户端(ssh)                       ssh服务端(sshd)

     +----------+                       +---------+
     |          |                       |         |
     |          |                       |         |
     |          |                       |         |
     |          |                       |         |
     +---+---+--+                       +-+---+---+
         |   |                            |   |
         |   |                            |   |
         |   +----------------------------+   |
         |                                    |
         |        ssh加密了的TCP通信            |
         +------------------------------------+

                    SSH连接

在客户端来看,SSH 提供两种级别的安全验证:

  • 第一种级别(基于密码的安全验证),知道帐号和密码,就可以登录到远程主机,并且所 有传输的数据都会被加密。但是,可能会有别的服务器在冒充真正的服务器,无法避免被 “中间人"攻击。
  • 第二种级别(基 于密钥的 安全验证),需要依靠密钥,也就是你必须为自己创建一对密钥,并把公有密钥放在需 要访问的服务器上。客户端软件会向服务器发出请求,请求用你的密钥进行安全验证。 服务器收到请求之后,先在你在该服务器的用户根目录下寻找你的公有密钥,然后把它和 你发送过来的公有密钥进行比较。如果两个密钥一致,服务器就用公有密钥加密"质询 “(challenge)并把它发送给客户端软件。从而避免被"中间人"攻击。

在服务器端,SSH 也提供安全验证:

  • 在第一种方案中,主机将自己的公用密钥分发给相关的客户端,客户端在访问主机时则使 用该主机的公开密钥来加密数据,主机则使用自己的私有密钥来解密数据,从而实现主机 密钥认证,确保数据的保密性。
  • 在第二种方案中,存在一个密钥认证中心,所有提供服务的主机都将自己的公开密钥提交 给认证中心,而任何作为客户端的主机则只要保存一份认证中心的公开密钥就可以了。在 这种模式下,客户端必须访问认证中心然后才能访问服务器主机。

how_does_the_ssh_protocol_work

SSH 服务端和客户端程序

SSH 只是一种协议,其开源实现有 OpenSSH 程序。

OpenSSH (OpenBSD Secure Shell) 是一套使用 ssh 协议,通过计算机网络,提供加密 通讯会话的计算机程序

如果需要作为 ssh 的服务端,则需要安装 openssh 程序。

如果仅是作为 ssh 客户端,在 Linux 中直接使用ssh命令即可。

在 Windows 中的 ssh 客户端程序有:

  • Putty
  • PuTTY Tray(Putty 的加强版)
  • Bitvise 的 ssh client (功能多,自带 sftp,免费) 推 荐
  • Xshell (2017 年被爆多版本存在后门)
  • SecureCRT(算了吧)

SSH Key

SSH 密钥对 最直观的作用:让你方便的登录到 SSH 服务器,而无需输入密码。由 于你无需发送你的密码到网络中,SSH 密钥对被认为是更加安全的方式。

原因是:SSH 利用 SSH Key 来进行前面提到的基于密钥的安全验证。

使用 SSH key 的步骤:

  • 在客户端生成 SSH key(密钥对:公钥和私钥)
  • 在服务端的配置文件中加入你的公钥。(比如我们需要再 GitHub 中粘贴你的公钥)

生成密钥对

ssh-keygen 命令用于为 ssh 生成、管理和转换认证密钥,它支持 RSA 和 DSA 两种认 证密钥。

该命令的选项:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 常用的选项
-b:指定密钥长度;
-C:添加注释;用于为指定注释,可以是任何内容,通常使用自己的邮件名作为注释。
-f:指定用来保存密钥的文件名;
-t:指定要创建的密钥类型(加密方式)。

-e:读取openssh的私钥或者公钥文件;
-i:读取未加密的ssh-v2兼容的私钥/公钥文件,然后在标准输出设备上显示openssh兼容的私钥/公钥;
-l:显示公钥文件的指纹数据;
-N:提供一个新密语;
-P:提供(旧)密语;
-q:静默模式;

生成密钥对时,有一个选项要求你设置密码(passphrase),该密码是用来保护你的私钥的 密码。如果设置了则在使用私钥时会要求你输入这个密码;一般不设置,记不住【之后 还可更改此密码,使用ssh-keygen -p】。

生成后最好将私钥进行备份。

常用的两者加密方式:

  • 为了安全考虑如果使用 RSA 加密方式则指定密钥长度为 -b 4096(1024 的密钥长度能 够被破解,建议指定为 4096)。
  • 但现在有了更安全的加密方式 ed25519 ,这是目前最受推荐的公钥算法。当使用 ed25519 加密方式时,它会忽略 -b 选项,因为它的长度是固定的。生成的密钥更紧凑 、更短(仅包含 68 个字符)、在签名验证时也更快并且还更安全。它还将使用新的 OpenSSH 格式(OpenSSH 6.5+)而不是 PEM 格式保存私钥,Windows10 中的 OpenSSH 最 先支持的也是 ed25519 类型的密钥。

使用 rsa 加密方式的示例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
[fan 16:10:57]~$ ssh-keygen -t rsa -C "[email protected]" -b 4096
Generating public/private rsa key pair.
# 指定密钥文件名称;直接回车则使用默认名称 id_rsa
Enter file in which to save the key (/home/fan/.ssh/id_rsa): /home/fan/.ssh/FDGitHub_rsa
# 输入密码(一般不输入密码,直接回车)
Enter passphrase (empty for no passphrase):
# 再次输入密码
Enter same passphrase again:
Your identification has been saved in /home/fan/.ssh/FDGitHub_rsa.
Your public key has been saved in /home/fan/.ssh/FDGitHub_rsa.pub.
The key fingerprint is:
SHA256:GcK7ORvFzH6fzA7qPmnzBr1DOWho5cCVgIpLkh6VGb8 [email protected]
The key's randomart image is:
+---[RSA 4096]----+
|   .+... .       |
|   +o.  o        |
| o.. oo..        |
|+o.   +*.o       |
|+..  E.=So .     |
|..    o== =      |
|     .=..+oo     |
|       +=o+= .   |
|      .++=.o*    |
+----[SHA256]-----+

# 查看公钥文件中的内容
$ cat ~/.ssh/FDGitHub_rsa.pub
ssh-rsa "公钥内容" [email protected]

# 注意在其他地方导入公钥时一定要将公钥文件中的 *全部内容* 都导入,包括末尾你的邮箱。

使用 ed25519 加密方式生成密钥的示例:

1
2
3
4
5
ssh-keygen -t ed25519 -C "[email protected]"

# 默认的密钥文件中将带有ed25519,比如:
~/.ssh/id_ed25519
~/.ssh/id_ed25519.pub

公钥是一串很长的字符;为了便于肉眼比对和识别,所以有了指纹这东西;指纹位数短 ,更便于识别且与公钥一一对应。

公钥加密指纹 fingerprint 有两种形式:

  • 之前的十六进制形式:16:27:ac:a5:76:28:2d:36:63:1b:56:4d:eb:df:a6:48
  • 现在使用 sha256 哈希值并且使用 base64 进行格式 :SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8

指纹的用处之一是在使用 SSH 第一次连接到某主机时,会返回该主机使用的公钥的指纹让 你识别。示例:

The authenticity of host '某主机名' can't be established.
RSA key fingerprint is SHA256:nThbg6kXUpJWGl7E1IGOCspRomTxdCARLviKw6E5SY8.
Are you sure you want to continue connecting (yes/no)?

简单介绍一下:
公钥用于给别人用来加密文件。公钥就是一把锁,你把锁给别人,他用锁锁住东西后,除 了你自己外其他人是没有钥匙(私钥)的,都无法打开。配对的私钥就是钥匙。
必须保证使用你的公钥的人明确知道这个公钥一定是你的。你可以在网站或通过其它方式 公布你的公钥,以便他人进行对照确认。由于公钥很长,所以有了对应的指纹(指纹更易 辨别,位数更少),可以通过指纹进行对照(公布指纹)。

如何创建多个 ssh key 而不是覆盖默认文件

在创建 ssh key 时自行输入路径和文件名称,而非使用默认路径和文件名即可。

或者使用 -f来指定文件名

ssh-keygen -t rsa -C "[email protected]" -f ~/.ssh/second-rsa

使用非默认的 SSH key

对于 OpenSSH 客户端(Linux 默认安装),需要在 ~/.ssh/config 文件中进行配置。

分为如下两种情况。

1.为不同服务器的同一用户配置不同 SSH key

这里同一用户在不同服务器上可以使用同一个 SSH key

Working with non-default SSH key pair paths

比如:你在 GitLab 上粘贴的公钥(Public SSH keys)不是默认的密钥对;此时要想让你的 ssh client 正常与 GitLab 服务器通信,必须对 ssh client 进行配置,当通信对象为 GitLab 服务器主机时,使用哪个私钥(SSH private key)。

注意:这里使用公钥也是可以的

示例:

1
2
3
4
5
6
7
# GitLab.com server
Host gitlab.com
IdentityFile ~/.ssh/private-key-filename-01

# Private GitLab server
Host gitlab.company.com
IdentityFile ~/.ssh/private-key-filename

**对于 GitLab 等:**上传到 GitLab 服务器中的 SSH 公钥只能属于单个用户,你的 SSH 密钥是您通过 SSH 推送代码时的标识符;它需要唯一映射到单个用户。也就是说,一个 公钥在该服务器上只能被一个账户使用;但是你可以在不同的服务器上使用同一个密钥对, 也可以在不同服务器上分别使用不同的密钥对

GitHub 使用非默认密钥对:

1
2
3
Host github.com
# 也可以使用公钥
IdentityFile ~/.ssh/FDGitHub_rsa.pub

配置完成后可以使用如下命令测试连接:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# 测试时替换掉 example.com
ssh -T [email protected]
# 例如 gitlab
ssh -T [email protected]
# 例如 github
ssh -T [email protected]
# 例如 coding
ssh -T [email protected]
# 例如 码云
ssh -T [email protected]
# bitbucket
ssh -T [email protected]

# 也可以使用下面的命令来调试连接
ssh -Tv [email protected]

如果测试时出现如下提示: Unsupported option "rsaauthentication",则可以选择 忽略或注释掉配置文件中的 RSAAuthentication yes行。

2.配置多个账户

为同一服务器配置不同账户,比如说你在 coding 上有两个账户,那么可以这样在 config 文件中配置:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# coding
Host git.coding.net
User [email protected]
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa  //默认的私钥

# second
Host git.coding.net
User [email protected]
PreferredAuthentications publickey
IdentityFile ~/.ssh/second_rsa  // 生成的第二个私钥

配置好之后,如果不能正常运行,需要将下面的内容添加到 .bashrc 文件中

1
2
3
4
# 如果 ssh-agent 没有启动,则启动
eval $(ssh-agent -s)
# 将非默认密钥添加给 ssh-agent 管理
ssh-add ~/.ssh/other_id_rsa

SSH agent

ssh agent ,意为 ssh 代理,是一个密钥管理器,用来管理一个多个密钥。

另见我的 ssh-agent

Github/GitLab 中为什么会用到 SSH?

Using the SSH protocol, you can connect and authenticate to remote servers and services. With SSH keys, you can connect to GitHub without supplying your username or password at each visit.

使用 SSH 协议,您可以连接和验证远程服务器和服务。

使用 SSH 密钥,您可以连接到 GitHub,而无需在每次访问时提供用户名或密码。

与 Github 主机进行通信的两种方式

访问远程仓库时可以选择 SSH 或者 HTTPS 协议进行访问。

(比如,与 gitlab 远程仓库进行进行安全认证可选择使用 ssh 或者 https),两者的表现 形式:

SSH  [email protected]:faner/test01.git
HTTPS  https://gitlab.com/faner/test01.git

当你选择 HTTPS 时,会看到它有下面的一段提示"Create a personal access token on your account to pull or push via Https"简单的翻译一下就是"在您的帐户上创建个人 访问令牌,以通过 Https 进行 pull 或 push”,并且在你第一次将本地仓库 push 到远 程仓库时会要求你输入 gitlab 的用户名和密码。

GitHub/GitLab 中导入 SSH Key

SSH Key 导入 :导入过程比较简单。

GitHub: 点击用户头像 > Setting > SSH and GPG keys > New SSH key > 粘贴你生成的 公钥(简单的方法是用文本编辑器打开公钥文件然后复制)。

那么现在您已经设置了 SSH 密钥,在下次克隆存储库时可以使用 SSH 的 URL。如果您已经 拥有通过 HTTPS 克隆的存储库,可以将存储库的远程 URL 更改为其 SSH URL 。

从用户操作上来看,HTTPS 需要用户输入远程仓库的用户名和密码,比如需要输入 gitlab 的帐号和密码;SSH 无需输入用户和密码。

问题:生成 ssh key 所使用的邮箱是否需要和本地 git 设置的邮箱相同?

本地 git 中配置的用户名和邮箱会随同提交日志被公开到 GitHub 上,而非生成 ssh key 时使用的邮箱(两者之间没有必然关系)。

参考

您的鼓励是我最大的动力
alipay QR Code

Felix
作者
Felix
如无必要,勿增实体。

3

目录