当前位置:   article > 正文

SSH原理与运用_使用rsa算法,生成一个备注名为hadoop,4096位的密钥对,用于ssh登录,使用的代码是ss

使用rsa算法,生成一个备注名为hadoop,4096位的密钥对,用于ssh登录,使用的代码是ss

SSH原理与运用

SSH原理与运用(一):远程登录

SSH原理与运用(二):远程操作与端口转发

一. 什么是SSH?

简单说,SSH是一种网络协议,用于计算机之间的加密登录。需要指出的是,SSH只是一种协议,存在多种实现,既有商业实现,也有开源实现。SSH的默认端口是22,也就是说,你的登录请求会送进远程主机的22端口。SSH之所以能够保证安全,原因在于它采用了公钥加密。整个过程是这样的:(1)远程主机收到用户的登录请求,把自己的公钥发给用户。(2)用户使用这个公钥,将登录密码加密后,发送回来。(3)远程主机用自己的私钥,解密登录密码,如果密码正确,就同意用户登录。

二. 中间人攻击

上面那个过程本身是安全的,但是实施的时候存在一个风险:如果有人截获了登录请求,然后冒充远程主机,将伪造的公钥发给用户,那么用户很难辨别真伪。因为不像https协议,SSH协议的公钥是没有证书中心(CA)公证的,也就是说,都是自己签发的。

可以设想,如果攻击者插在用户与远程主机之间(比如在公共的wifi区域),用伪造的公钥,获取用户的登录密码。再用这个密码登录远程主机,那么SSH的安全机制就荡然无存了。这种风险就是著名的"中间人攻击"(Man-in-the-middle attack)。

SSH协议是如何应对的呢?

如果你是第一次登录对方主机,系统会出现下面的提示:

	$ ssh user@host

	The authenticity of host 'host (12.18.429.21)' can't be established.

  RSA key fingerprint is 98:2e:d7:e0:de:9f:ac:67:28:c2:42:2d:37:16:58:4d.

  Are you sure you want to continue connecting (yes/no)?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

这段话的意思是,无法确认host主机的真实性,只知道它的公钥指纹,问你还想继续连接吗?

所谓"公钥指纹",是指公钥长度较长(这里采用RSA算法,长达1024位),很难比对,所以对其进行MD5计算,将它变成一个128位的指纹。

很自然的一个问题就是,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对

假定经过风险衡量以后,用户决定接受这个远程主机的公钥。

  Are you sure you want to continue connecting (yes/no)? yes
  • 1

系统会出现一句提示,表示host主机已经得到认可。

  Warning: Permanently added 'host,12.18.429.21' (RSA) to the list of known hosts.
  • 1

然后,会要求输入密码。

  Password: (enter password)
  • 1

如果密码正确,就可以登录了。

当远程主机的公钥被接受以后,它就会被保存在文件$HOME/.ssh/known_hosts之中。下次再连接这台主机,系统就会认出它的公钥已经保存在本地了,从而跳过警告部分,直接提示输入密码。

每个SSH用户都有自己的known_hosts文件,此外系统也有一个这样的文件,通常是/etc/ssh/ssh_known_hosts,保存一些对所有用户都可信赖的远程主机的公钥。

三. 最基本的用法

SSH主要用于远程登录。假定你要以用户名user,登录远程主机host,只要一条简单命令就可以了。

$ ssh user@host   // 或者 ssh root@公网IP
  • 1

四. 公钥登录

参考链接:SSH免密登录

使用密码登录,每次都必须输入密码,非常麻烦。好在SSH还提供了公钥登录,可以省去输入密码的步骤。

  1. 生成公钥和私钥
ssh-keygen
  • 1

在这里插入图片描述
默认名称为id_rsa和id_rsa.pub,也可以自定义名称,方便区分,例如:
在这里插入图片描述
在上面截图里的.ssh文件夹下有个authorized_keys文件,这个代表授权的key,也就是你往目标登录主机上放的公钥。

  1. 把公钥拷贝到远程服务
scp id_ed25519.pub root@公网IP:/root/.ssh
  • 1
  1. 在远程服务器上,将公钥拷贝到authorized_keys里
cat >> authorized_keys < id_xxx.pub
  • 1
  1. 重启ssh服务
systemctl restart sshd
  • 1

内网穿透工具

Serveo 是一款免费的 SSH 隧道服务,可以将内网服务映射到公网上,以便外部用户能够访问。以下是使用 Serveo 的简单步骤:

  1. 打开终端并运行以下命令:
   ssh -R 80:localhost:8080 serveo.net
  • 1

这将将本地的 8080 端口映射到 Serveo 提供的公网域名上的 80 端口。

  1. Serveo 将为您生成一个随机的公网域名,并将其与您的本地服务绑定。例如,Serveo 可能会生成一个类似于 https://randomname.serveo.net 的域名。

  2. 您现在可以通过访问生成的公网域名来访问您的内网服务。例如,在上述示例中,您可以通过 https://randomname.serveo.net 访问本地的服务。

需要注意的是,Serveo 的免费服务是基于 SSH 隧道实现的,并且每次启动都会生成一个新的随机域名。如果您需要使用固定的公网域名或其他高级功能,则可能需要考虑使用其他付费的内网穿透工具或服务。

The authenticity of host ‘serveo.net (138.68.79.95)’ can’t be established.RSA key fingerprint is SHA256:07jcXlJ4SkBnyTmaVnmTpXuBiRx2+Q2adxbttO9gt0M.Are you sure you want to continue connecting (yes/no/[fingerprint])?

SSH应用

这是一个 SSH 连接时的提示信息,询问您是否确认连接到指定的主机(serveo.net),并显示了该主机的 RSA 密钥指纹。您可以输入 “yes” 确认连接,然后您的 SSH 客户端会将该密钥指纹保存到本地,以便以后连接时进行验证。如果您不确定该密钥指纹是否正确,可以比对该指纹是否与服务提供商提供的指纹匹配。

上面的 RSA key fingerprint 是 SSH 服务器的公钥经过某一个hash算法计算出来的值。

SSH 服务器的公钥指纹用于验证 SSH 服务器的身份,以确保客户端连接的是正确的服务器,而不是中间人攻击者伪造的服务器。在 SSH 连接时,客户端会将其保存在本地的已知主机列表中,以便将来连接时进行验证。

在第一次连接时,用户怎么知道远程主机的公钥指纹应该是多少?回答是没有好办法,远程主机必须在自己的网站上贴出公钥指纹,以便用户自行核对

下面以阿里云为例,我们通过密码登录云主机,查看云主机 /etc/ssh下面的公私钥对,然而我们发现好多对:
在这里插入图片描述
在 SSH 服务器上,通常有一个主机密钥对应的公钥以及每个用户账户都有一个 authorized_keys 文件,其中包含了该用户允许连接到该账户的公钥列表。

当远程用户尝试连接到服务器时,服务器会使用以下步骤来选择正确的公钥进行验证:

  1. 主机密钥:
    服务器使用主机密钥对应的公钥进行初始连接的身份验证。这是服务器身份的一部分,用于确保你连接到的是预期的服务器。主机密钥通常存储在 /etc/ssh 目录下的 ssh_host_*_key.pub 文件中。

  2. 用户密钥:
    一旦通过了主机密钥的验证,服务器将要求用户提供其对应的密钥进行用户身份验证。这是通过检查用户的 ~/.ssh/authorized_keys 文件,其中包含了允许连接到该用户账户的所有公钥。

    如果用户提供了有效的密钥,连接将被授予;否则,连接将被拒绝。

  3. 多个用户公钥:
    如果用户在 authorized_keys 文件中有多个公钥,服务器将逐个尝试进行验证,直到找到匹配的公钥或者所有的公钥都被尝试完毕。验证通过即允许连接。

总之,服务器在连接时会先使用主机密钥进行验证,然后再使用用户提供的公钥进行用户身份验证。用户的公钥列表存储在其 authorized_keys 文件中,如果有多个公钥,服务器会逐个尝试验证。连接将在找到有效的公钥或者所有公钥都尝试完毕后被授予或拒绝。


当然,我们也可以通过ssh免密登录远程服务器:

使用 SSH 公私钥对连接远程服务器,通常遵循以下步骤:

  1. 生成 SSH 密钥对:
    在本地机器上使用以下命令生成 SSH 密钥对。如果你已经有密钥对,可以跳过这一步。

    ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa
    
    • 1

    上述命令会生成一个 2048 位的 RSA 密钥对,并将私钥保存在 ~/.ssh/id_rsa,公钥保存在 ~/.ssh/id_rsa.pub

  2. 复制公钥到远程服务器:
    将本地生成的公钥复制到远程服务器的 ~/.ssh/authorized_keys 文件中。你可以使用 SSH 命令或其他文件传输工具完成此操作。
    在这里插入图片描述

  3. 连接到远程服务器:

    ssh user@remote_server
    
    • 1

    如果一切设置正确,你应该能够通过公私钥进行连接,而无需输入服务器密码,但是需要输入本机密码,以便安全访问你本机的私钥。
    在这里插入图片描述


SSH 是一个常用的网络协议,用于安全地远程连接和管理服务器。以下是在常见操作系统上安装 SSH 的简要步骤:

  1. 打开终端。
  2. 输入以下命令来安装 OpenSSH:sudo apt-get install openssh-server

使用方式:

生成 SSH 公钥和私钥通常使用的软件是 OpenSSH。以下是在 Linux、macOS 和 Windows 上生成 SSH 公钥和私钥的步骤:

在 Linux 和 macOS 上:

  1. 打开终端。
  2. 输入以下命令来生成 SSH 密钥对:
   ssh-keygen -t rsa -b 4096
  • 1

这将使用 RSA 算法生成一个 4096 位的密钥对。
3. 按提示输入密钥的保存路径和密码(可选)。
4. 生成的公钥和私钥文件默认保存在 ~/.ssh 目录下,分别是 id_rsa.pub(公钥)和 id_rsa(私钥)。

生成的公钥文件(以 .pub 结尾)是用于共享给其他人或服务器,而私钥文件应妥善保管,不应泄露给他人。公钥可用于身份验证和加密通信

SSH的使用场景:

  1. 远程服务器管理:SSH 可以让系统管理员通过安全的方式远程登录和管理服务器,执行系统维护、软件安装、日志查看等操作。
  2. 文件传输:SSH 提供了 SCP(Secure Copy)和 SFTP(SSH File Transfer Protocol)等工具,可以安全地传输文件到远程主机或从远程主机下载文件。
  3. 远程开发和调试:开发人员可以使用 SSH 连接到远程开发环境,进行代码编写、调试和测试,而无需在本地设置开发环境。
  4. 安全代理和隧道:SSH 可以用作安全代理,通过隧道将本地端口转发到远程主机,实现安全访问内部网络资源或绕过防火墙限制。
  5. 远程访问内网服务:通过 SSH 隧道或端口转发,可以安全地访问内网服务,如数据库、Web 应用程序等。

这些只是 SSH 的一些常见使用场景,它在保护数据传输安全、远程管理和访问控制等方面发挥着重要作用。

例如:

  1. 打开终端或命令行界面。
  2. 使用以下命令连接到远程主机:
   ssh username@hostname
  • 1

其中,username 是您在远程主机上的用户名,hostname 是远程主机的 IP 地址或域名。

  1. 输入远程主机的密码或使用 SSH 密钥进行身份验证。
  2. 连接成功后,您可以在远程主机上执行命令、传输文件等操作。

SHA-1、SHA-256和RSA的区别

  • SHA-1和SHA-256都是哈希函数算法,用于生成数据的摘要;
  • RSA是一种非对称加密算法,用于加密、解密、数字签名和身份验证。

在实际应用中,常常会将RSA与SHA算法结合使用,以提供更安全的加密和签名机制。在数字签名过程中,通常会使用RSA与SHA算法结合,先使用SHA算法对数据进行哈希,然后使用RSA私钥对哈希值进行加密生成数字签名,再使用RSA公钥进行验证。

公钥验证数字签名demo:

公钥验证数字签名的过程如下:

  1. 获取要验证的数据、公钥和数字签名。
  2. 使用公钥对数字签名进行解密,得到解密后的数据。
  3. 对要验证的数据进行哈希计算,通常使用与创建数字签名时相同的哈希算法。
  4. 将哈希计算得到的结果与解密后的数据进行比较。
  5. 如果两者完全一致,则表明数字签名有效,验证通过;否则,数字签名无效,验证失败。

公钥验证通常是1. 通过使用公钥对数字签名解密后,得到hash值;2. 对data数据进行hash。3. 比较两个hash值是否一样来实现的。
以下是一个使用 Node.js 进行公钥验证的示例代码:

const crypto = require('crypto');
const fs = require('fs');

// 要验证的数据
const data = '要验证的数据';

// 读取公钥文件
const publicKey = fs.readFileSync('public_key.pem', 'utf8');

// 读取数字签名文件,一般跟随接口下发
const signature = fs.readFileSync('signature.txt', 'utf8');

// 创建 Verify 对象
const verifier = crypto.createVerify('SHA256');

// 将要验证的数据传递给 verifier 对象
verifier.update(data);
verifier.end();

// 进行验证
const isValid = verifier.verify(publicKey, signature, 'base64');

if (isValid) {
  console.log('数字签名验证通过');
} else {
  console.log('数字签名验证失败');
}
  • 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

在上述代码中,我们使用 Node.js 的 crypto 模块进行公钥验证。首先,我们读取公钥文件和数字签名文件的内容。然后,创建一个 Verify 对象,并设置要验证的数据。接下来,我们使用 verify 方法对数据进行验证,传入公钥、数字签名和编码方式(这里使用了 base64 编码)。最后,根据验证结果输出相应的消息。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/492078
推荐阅读
相关标签
  

闽ICP备14008679号