当前位置: 首页 > news >正文

Linux小课堂: SSH协议中的加密机制:对称加密与非对称加密的融合原理

引言:加密算法的基本概念

在信息安全传输中,加密算法(Encryption Algorithm) 是核心基础。所谓“算法”(Algorithm),是指一系列解决特定问题的清晰指令集合,它系统性地描述了某种策略或机制。在数据安全领域,加密算法用于将明文信息转换为不可读的密文,以防止未经授权的访问

加密算法广泛应用于保护敏感信息在传输或存储过程中的机密性。对于开发者而言,理解不同类型的加密机制是构建安全通信体系的基础。

尽管加密算法种类繁多,但从密钥使用方式上可划分为两大类:

  • 对称加密(Symmetric Key Encryption)
  • 非对称加密(Asymmetric Key Encryption)

这两类算法构成了现代密码学的基础,也是 SSH 协议实现安全通信的关键支柱

对称加密:高效但存在密钥分发难题

对称加密,全称为“对称密钥加密”,其特点是加密与解密使用同一个密钥。例如,若客户端用密钥 superkey 对明文 message 进行加密,生成密文 %i5%xman,则服务器必须使用相同的密钥 superkey 才能将其还原为原始明文

对称加密,全称为“对称密钥加密”,其核心特征在于:加密和解密使用同一个密钥。该密钥被称为共享密钥(Shared Secret),必须由通信双方事先协商并安全保存

工作原理示例:

假设客户端要向服务器发送一条明文消息 "message",使用的对称密钥为 "superkey"

  1. 客户端使用 superkey"message" 进行加密,生成密文(如 i5%xman
  2. 服务器接收到密文后,使用相同的 superkey 执行解密操作,还原出原始明文

由于加密与解密过程依赖同一把钥匙,因此只要密钥不被泄露,即使密文被截获,攻击者也无法解读内容

然而,问题随之而来:如何安全地将初始密钥传递给对方?

若通过网络以明文形式传输 superkey,则中间人(MITM, Man-in-the-Middle)可轻易截获该密钥,并用于后续所有通信的解密。这使得整个加密体系形同虚设

因此,对称加密虽然运算速度快、效率高,但面临严峻的“密钥分发”挑战

// 示例:Node.js 中使用 AES 对称加密(NestJS 环境)
import { createCipheriv, createDecipheriv } from 'crypto';const ALGORITHM = 'aes-256-cbc';
const KEY = Buffer.from('superkey'.padEnd(32, '\0')); // 256位密钥
const IV = Buffer.from('1234567890123456'); // 初始化向量export class SymmetricEncryptionService {encrypt(plaintext: string): string {const cipher = createCipheriv(ALGORITHM, KEY, IV);let encrypted = cipher.update(plaintext, 'utf8', 'hex');encrypted += cipher.final('hex');return encrypted;}decrypt(ciphertext: string): string {const decipher = createDecipheriv(ALGORITHM, KEY, IV);let decrypted = decipher.update(ciphertext, 'hex', 'utf8');decrypted += decipher.final('utf8');return decrypted;}
}

核心特点总结:

  • 加密和解密使用同一个密钥
  • 算法效率高,适合大量数据传输
  • 最大缺陷:密钥必须提前安全共享——若通过明文传输,则极易被中间人截获,导致整个加密体系崩溃

这种方式简单高效,性能优越,适合大量数据的加解密操作。然而,其致命缺陷在于:如何安全地共享密钥?

如果客户机将密钥 superkey 以明文方式发送给服务器,攻击者一旦截获即可解密所有后续通信内容。因此,直接在网络上传输对称密钥是极不安全的。

非对称加密:解决密钥交换的安全通道构建

为了克服对称加密的密钥分发问题,引入了非对称加密(Asymmetric Key Encryption)
该机制使用一对数学上相关联的密钥:公钥(Public Key) 和 私钥(Private Key)

  • 公钥用于加密,可以公开传播
  • 私钥用于解密,必须严格保密

核心概念:

  • 每个用户拥有一对密钥:公钥(Public Key) 和 私钥(Private Key)
  • 公钥用于加密,可公开传播
  • 私钥用于解密,必须严格保密
  • 加密只能用公钥,解密只能用私钥,二者不可互换

二者成对生成,且无法从公钥推导出私钥。典型代表是 RSA 算法,由 Rivest、Shamir 和 Adleman 于1977年提出,至今仍是广泛应用的标准之一

RSA 算法背景:

RSA 由 Ron Rivest、Adi Shamir 和 Leonard Adleman 三位学者于1977年提出,以其姓氏首字母命名
其安全性基于大整数分解难题——即两个极大质数相乘容易,但将其乘积逆向分解极为困难

示例流程:

设有一对密钥:

  • 公钥:2K49C8UE
  • 私钥:5Z3S26LN

当客户端欲发送信息时:

  1. 使用服务器提供的公钥 2K49C8UE 加密明文 "message",得到密文 `i5%xman
  2. 服务器收到密文后,使用自己的私钥 5Z3S26LN 解密,恢复原文

即便攻击者截获了公钥和密文,由于缺乏私钥,仍无法完成解密
关键点:公钥可自由传播,私钥绝不暴露

工作流程如下:

  1. 客户端使用服务器的公钥加密一段信息(如对称密钥 superkey
  2. 加密后的结果只能由持有对应私钥的服务器解密
  3. 即使攻击者截获加密数据和公钥,也无法推导出私钥或原始信息
// 示例:Node.js 中使用 RSA 非对称加密(NestJS 环境)
import { generateKeyPairSync, publicEncrypt, privateDecrypt } from 'crypto';export class AsymmetricEncryptionService {private publicKey: string;private privateKey: string;constructor() {const keyPair = generateKeyPairSync('rsa', {modulusLength: 2048,publicKeyEncoding: { type: 'spki', format: 'pem' },privateKeyEncoding: { type: 'pkcs8', format: 'pem' },});this.publicKey = keyPair.publicKey;this.privateKey = keyPair.privateKey;}encryptWithPublicKey(data: string): Buffer {return publicEncrypt(this.publicKey, Buffer.from(data));}decryptWithPrivateKey(encryptedData: Buffer): string {return privateDecrypt(this.privateKey, encryptedData).toString('utf8');}
}

核心特点总结:

  • 使用两个不同的密钥完成加解密
  • 安全性极高,即使公钥泄露也不会影响私钥安全
  • 缺点:计算复杂度高,速度比对称加密慢 100~1000 倍,不适合频繁大数据加密

SSH 如何融合两种加密方式构建安全管道


SSH 并未选择单一加密模式,而是采用一种混合加密策略,充分发挥两者优势:

核心策略:先用非对称加密安全交换对称密钥,再用对称加密进行后续通信

安全密钥交换过程详解

以下是 SSH 建立安全连接的典型步骤:

步骤①:服务器发送公钥给客户端

  • 服务器生成一对非对称密钥(公钥 + 私钥)
  • 将公钥以明文形式发送给客户端(例如:2K49C8UE

步骤②:客户端生成对称密钥并用公钥加密

  • 客户端本地生成一个临时的对称密钥(如:superkey
  • 使用服务器提供的公钥对其加密 → 得到密文(如:CH4bSn6s

步骤③:客户端发送加密后的对称密钥

  • 将加密后的对称密钥传回服务器
  • 攻击者即使截获该密文,也无法解密(缺少私钥)

步骤④:服务器用私钥解密获取对称密钥

  • 服务器使用自己的私钥(如:5Z3S26LN)解密得到 superkey
  • 至此,双方均掌握同一对称密钥,但从未在网络上明文传输过

步骤⑤:启用对称加密进行高效通信

  • 后续所有通信(包括用户名、密码、命令执行等)均使用 superkey 进行对称加密
  • 保证了高性能与高安全性
// 综合服务:模拟 SSH 密钥协商与加密通信流程
@Injectable()
export class SshEncryptionOrchestrator {private symmetricKey: string | null = null;private readonly asymmetricService = new AsymmetricEncryptionService();private readonly symmetricService = new SymmetricEncryptionService();// 模拟服务器端:提供公钥,接收加密密钥,解密获得对称密钥providePublicKey(): string {return this.asymmetricService.publicKey;}receiveEncryptedSymmetricKey(encryptedKey: Buffer): void {this.symmetricKey = this.asymmetricService.decryptWithPrivateKey(encryptedKey);console.log('[Server] Symmetric key received:', this.symmetricKey);}// 模拟客户端:获取公钥,生成并加密对称密钥async initiateHandshake(serverPublicKey: string): Promise<Buffer> {const tempSymmetricKey = 'superkey'; // 实际应随机生成const cipher = createCipheriv('rsa', serverPublicKey, null);return publicEncrypt(serverPublicKey, Buffer.from(tempSymmetricKey));}// 双方建立会话后,使用对称加密通信sendMessage(message: string): string {if (!this.symmetricKey) throw new Error('No symmetric key established.');return this.symmetricService.encrypt(message);}receiveMessage(encryptedMessage: string): string {if (!this.symmetricKey) throw new Error('No symmetric key established.');return this.symmetricService.decrypt(encryptedMessage);}
}

为什么不能全程使用非对称加密?

因为非对称加密运算开销极大,每条消息都使用会导致性能严重下降。而对称加密速度快、资源消耗低,适合持续通信。因此,SSH 仅在初始阶段使用非对称加密来“护送”对称密钥,之后切换至高效的对称加密模式

SSH协议的工作机制:结合两种加密方式的优势


SSH(Secure Shell)协议巧妙地融合了非对称加密与对称加密的优点,既保证了安全性,又兼顾了效率

安全通信管道的建立过程,整个流程分为两个阶段:

阶段一:通过非对称加密安全交换对称密钥

  1. 服务器生成 RSA 密钥对,并将 公钥 明文发送给客户端;
  2. 客户端随机生成一个对称加密密钥(如 superkey);
  3. 客户端使用服务器的公钥对该对称密钥进行加密;
  4. 加密后的对称密钥被传回服务器;
  5. 服务器使用自己的私钥解密,获得原始对称密钥;
  6. 至此,双方均持有相同的对称密钥,且该密钥从未以明文形式出现在网络中。

这一过程确保了密钥交换的安全性,即使中间人截获加密后的对称密钥,也无法解密。

阶段二:使用对称加密进行高效通信

一旦对称密钥成功交换,后续的所有通信(包括身份验证、命令执行、文件传输等)均采用该密钥进行高速加解密。由于对称加密比非对称加密快约 100~1000倍,这极大地提升了整体性能。

为何不全程使用非对称加密?

尽管非对称加密更安全,但其计算开销大,不适合频繁的数据交互。SSH选择仅在初始握手阶段使用非对称加密来传递对称密钥,之后切换至高性能的对称加密,实现安全与效率的平衡。

NestJS 模拟 SSH 握手流程代码实现


1 )方案1

以下是一个基于 NestJS 的简化模拟服务端逻辑,展示 SSH 类似的密钥协商过程(仅作教学演示,不可用于生产):

// src/ssh/handshake.service.ts
import { Injectable } from '@nestjs/common';
import * as crypto from 'crypto';@Injectable()
export class HandshakeService {private serverKeys = this.generateServerKeyPair();private sharedSymmetricKey: string | null = null;generateServerKeyPair() {return crypto.generateKeyPairSync('rsa', {modulusLength: 2048,publicKeyEncoding: { type: 'spki', format: 'pem' },privateKeyEncoding: { type: 'pkcs8', format: 'pem' },});}getServerPublicKey(): string {return this.serverKeys.publicKey;}receiveEncryptedSymmetricKey(encryptedKey: Buffer): void {const decryptedKey = crypto.privateDecrypt(this.serverKeys.privateKey,encryptedKey,);this.sharedSymmetricKey = decryptedKey.toString();}isHandshakeComplete(): boolean {return !!this.sharedSymmetricKey;}decryptMessage(encryptedMessage: Buffer): string {if (!this.sharedSymmetricKey) throw new Error('No shared key established');return crypto.privateDecrypt(this.serverKeys.privateKey, encryptedMessage).toString();}
}
// src/ssh/handshake.controller.ts
import { Controller, Post, Body, Get } from '@nestjs/common';
import { HandshakeService } from './handshake.service';@Controller('ssh')
export class HandshakeController {constructor(private readonly handshakeService: HandshakeService) {}@Get('public-key')getPublicKey() {return { publicKey: this.handshakeService.getServerPublicKey() };}@Post('exchange-key')exchangeKey(@Body('encryptedKey') encryptedKey: Buffer) {this.handshakeService.receiveEncryptedSymmetricKey(Buffer.from(encryptedKey, 'base64'));return { status: 'success', message: 'Symmetric key received and decrypted' };}@Post('send-message')sendMessage(@Body('data') encryptedData: Buffer) {const decrypted = this.handshakeService.decryptMessage(Buffer.from(encryptedData, 'base64'));return { original: decrypted };}
}

上述代码模拟了:

  • 服务器暴露公钥
  • 客户端加密并上传对称密钥
  • 服务器解密后完成握手
  • 后续消息可通过对称密钥加密传输

2 ) 方案2

模拟 SSH 密钥管理与会话建立的服务模块,展示核心逻辑结构。

// ssh-keypair.service.ts
import { Injectable } from '@nestjs/common';
import * as crypto from 'crypto';interface KeyPair {publicKey: string;privateKey: string;
}@Injectable()
export class SshKeyPairService {/* 生成 RSA 非对称密钥对(模拟服务器行为)*/generateKeyPair(): KeyPair {const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {modulusLength: 2048,publicKeyEncoding: { type: 'spki', format: 'pem' },privateKeyEncoding: { type: 'pkcs8', format: 'pem', cipher: undefined },});return {publicKey: Buffer.from(publicKey).toString('base64'),privateKey: Buffer.from(privateKey).toString('base64'),};}/* 使用公钥加密数据(模拟客户端加密会话密钥)*/encryptWithPublicKey(publicKeyBase64: string, data: string): string {const publicKeyPem = Buffer.from(publicKeyBase64, 'base64').toString();const buffer = crypto.publicEncrypt(publicKeyPem, Buffer.from(data));return buffer.toString('base64');}/* 使用私钥解密数据(模拟服务器解密会话密钥)*/decryptWithPrivateKey(privateKeyBase64: string, encryptedData: string): string {const privateKeyPem = Buffer.from(privateKeyBase64, 'base64').toString();const buffer = crypto.privateDecrypt(privateKeyPem, Buffer.from(encryptedData, 'base64'));return buffer.toString();}
}
// ssh-session.service.ts
import { Injectable } from '@nestjs/common';
import { SshKeyPairService } from './ssh-keypair.service';@Injectable()
export class SshSessionService {private sessionKey: string | null = null;constructor(private readonly keyPairService: SshKeyPairService) {}/* 模拟完整 SSH 会话建立过程*/establishSecureChannel() {console.log('【SSH】开始建立安全通信通道...');// Step 1: 服务器生成密钥对 const serverKeys = this.keyPairService.generateKeyPair();console.log('✅ 服务器已生成非对称密钥对');// Step 2: 客户端生成对称会话密钥 const sessionSecret = 'superkey'; // 实际应为随机生成 console.log(`🔑 客户端生成会话密钥: ${sessionSecret}`);// Step 3: 客户端用服务器公钥加密会话密钥const encryptedSessionKey = this.keyPairService.encryptWithPublicKey(serverKeys.publicKey,sessionSecret,);console.log('🔒 会话密钥已使用公钥加密');// Step 4: 服务器使用私钥解密获得会话密钥 const decryptedSessionKey = this.keyPairService.decryptWithPrivateKey(serverKeys.privateKey,encryptedSessionKey,);// Step 5: 双方确认会话密钥一致if (decryptedSessionKey === sessionSecret) {this.sessionKey = sessionSecret;console.log('🔐 安全通道建立成功!后续通信将使用对称加密');} else {throw new Error('❌ 会话密钥协商失败');}}/* 获取当前有效的会话密钥*/getSessionKey(): string {if (!this.sessionKey) {throw new Error('No active session key. Please establish connection first.');}return this.sessionKey;}
}
// app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { SshSessionService } from './ssh-session.service';@Controller()
export class AppController {constructor(private readonly sshSessionService: SshSessionService) {}@Get('/ssh/connect')connectViaSSH() {try {this.sshSessionService.establishSecureChannel();const key = this.sshSessionService.getSessionKey();return {success: true,message: 'SSH 安全连接已建立',sessionKey: key,};} catch (error) {return {success: false,message: error.message,};}}
}

OpenSSH 的部署与管理:将本地机器配置为 SSH 服务端


要使一台机器支持 SSH 连接,需安装 OpenSSH 服务组件
OpenSSH 是 SSH 协议的开源实现,广泛应用于 Linux、macOS 及现代 Windows 系统

OpenSSH 架构组成

  • 客户端组件:openssh-client
    功能:发起 SSH 连接请求(如 ssh user@host
  • 服务端组件:openssh-server
    功能:监听 22 端口,接受远程连接请求,启动守护进程 sshd

1 ) 安装 OpenSSH Server

在基于 Red Hat 的发行版(如 CentOS、RHEL)中:

sudo yum install openssh-server -y

在 Debian/Ubuntu 系统中:

sudo apt update 
sudo apt install openssh-server -y

2 ) 管理 SSHD 守护进程

SSHD(SSH Daemon)是运行在后台的守护进程,负责监听 22 端口并处理连接请求。

常用 systemd 命令管理 SSHD:

启动 SSH 服务
sudo systemctl start sshd停止 SSH 服务
sudo systemctl stop sshd重启 SSH 服务
sudo systemctl restart sshd查看 SSH 服务状态 
sudo systemctl status sshd 设置开机自启 
sudo systemctl enable sshd 

sshd(SSH Daemon)是一个运行在后台的守护进程,监听默认端口 22,负责处理所有入站 SSH 请求

3 ) 配置文件路径

主配置文件位于 /etc/ssh/sshd_config,可修改监听端口、允许登录用户、禁用密码认证等高级设置。

修改后需重启服务生效:

sudo systemctl reload sshd 

SSH 加密机制的核心要点


要点内容
对称加密特点使用单一密钥加解密,速度快,适合大数据量通信
非对称加密特点使用公钥加密、私钥解密,安全性高,用于密钥交换
SSH 加密策略先非对称加密交换密钥,后对称加密通信,兼顾安全与效率
密钥传递安全性对称密钥从未明文传输,通过非对称加密保护
主流算法支持RSA 是最广泛使用的非对称算法;AES、3DES 等用于对称加密
OpenSSH 实现开源实现,包含客户端与服务端,可通过 systemctl 管理

SSH 加密体系的核心思想


特性对称加密非对称加密
密钥数量1个共享密钥1对密钥(公钥+私钥)
加密速度快(适合大数据量)慢(约慢100~1000倍)
安全性高,但密钥分发困难高,公钥可公开
应用场景数据传输加密密钥交换、数字签名

SSH 的精妙之处在于:

  • 利用非对称加密解决密钥分发的信任问题
  • 利用对称加密保障后续通信的高性能与低延迟
  • 整个过程自动完成,用户无需干预底层细节

SSH 协议的精髓在于:
利用非对称加密安全地交换对称密钥,再使用对称加密进行高效通信

SSH 协议的设计体现了密码学工程化的典范——不追求单一技术的极致,而是通过组合多种机制实现最优平衡。通过对称加密保障效率,通过非对称加密确保密钥交换安全,最终构建出一个坚不可摧的远程通信隧道

这种“先密钥协商、再加密通信”的模式,已成为现代网络安全协议的标准范式,广泛应用于 HTTPS、TLS、IPSec 等场景。深入理解其背后原理,不仅有助于掌握 SSH 使用技巧,更能提升整体系统安全设计能力

这种混合模式不仅解决了传统对称加密的密钥分发难题,也避免了全程使用非对称加密带来的性能瓶颈,体现了工程实践中“取长补短”的智慧设计

如今,全球绝大多数远程管理都依赖 SSH 协议,取代了早期不安全的 Telnet 和 rlogin 等明文传输协议
理解其底层加密机制,有助于深入掌握网络安全的本质逻辑

SSH 协议的设计同样也体现了计算机科学中经典的“分层思维”与“权衡艺术”。它没有追求理论上的绝对完美,而是基于现实约束(性能 vs 安全),构建了一个实用、可靠、自动化的安全通信框架

即便用户无需理解底层加密原理,也能通过简单的 ssh username@hostname 命令完成安全登录——这正是优秀系统设计的魅力所在:把复杂留给自己,把简单交给用户

http://www.dtcms.com/a/516709.html

相关文章:

  • MySQL----视图
  • 网站系统升级建设合同江西省美丽乡村建设公布网站
  • 已经具备GIS开发的能力,可以去哪些热门就业方向?
  • 福州++网站建设wordpress首页导航栏
  • Fruit框架:C++依赖注入解决方案
  • 《博弈论》
  • pw域名网站常州网站建设乛薇
  • 【Qt】TCP连接--客户端和服务器
  • 【CMakeLists.txt】 Qt 自动化构建配置详解
  • 分布式光伏气象站:专为户外光伏场景设计的气象监测设备
  • 网站模板是什么东莞全网推广
  • 高安网站建设公司网站优化就是搜索引擎优化
  • deadline调度学习
  • Shell 函数
  • 火星时代UE奶瓜粒子特效⑦
  • JS--正则表达式的用法
  • 为离职员工做的网站好的网站收入
  • AI智能体编程的未来方向有哪些?
  • 如何设置等长的最大走线长度
  • 搭建本地时间同步服务器
  • 百度前端面试核心考点深度解析(二)
  • 关于网站建设的电话销售话术建站之星安装模板失败
  • 对互联网网站的理解wordpress只能下载一个文件
  • 什么是MCP(python包和项目管理器uv)|常用mcp server整理(持续更新)
  • 基于MATLAB S函数实现多智能体间歇通信仿真
  • C++ 双向循环链表
  • LCC-S型磁耦合谐振无线电传输系统实现恒压输出simulink
  • 网站开始怎么做的徐州住房与城乡建设部网站
  • Visual Studio Code 高效开发完全指南(2025年更新版)
  • 汽车网站模版wordpress 标签页面