面试官常问的TCP三次握手与HTTPS的四次握手

背景

TCP 握手和 HTTPS 握手分别属于 OSI 网络模型中的不同层次,并且在网络通信中扮演着重要的角色。TCP(传输控制协议)是 OSI 模型中的传输层协议,负责提供可靠的数据传输。TCP 握手是 TCP 协议在建立连接时的一部分。HTTPS 握手属于应用层(Application Layer),HTTPS(安全的超文本传输协议)是一个基于 HTTP 协议的加密通信协议,用于在客户端和服务器之间建立安全的通信通道。

一、TCP 握手过程(三次握手):

过程

  • 第一次握手(SYN):客户端发送一个带有 SYN(同步)标志的 TCP 数据包给服务器,请求建立连接。此时客户端进入 SYN_SENT 状态。

  • 第二次握手(SYN + ACK):服务器收到客户端的请求后,发送一个带有 SYN 和 ACK(确认)标志的 TCP 数据包作为响应。此时服务器进入 SYN_RCVD 状态。

  • 第三次握手(ACK):客户端收到服务器的响应后,发送一个带有 ACK 标志的 TCP 数据包给服务器,确认连接建立。此时客户端和服务器都进入 ESTABLISHED 状态,可以开始传输数据。

注意: 这里的握手次数指的是建立连接所需的握手次数。关闭连接时,还需要进行四次挥手过程来正常关闭连接。

示例

下面是一个使用Node.js的示例代码,演示了TCP客户端和服务器之间的握手过程:

js 复制代码
// TCP服务器代码
const net = require('net');

const server = net.createServer((socket) => {
  socket.on('data', (data) => {
    console.log('Received data:', data.toString());
  });

  socket.on('end', () => {
    console.log('Connection closed by client');
  });
});

server.listen(3000, () => {
  console.log('TCP server listening on port 3000');
});

// TCP客户端代码
const net = require('net');

const client = net.createConnection({ port: 3000 }, () => {
  console.log('Connected to TCP server');

  client.write('Hello server!');
});

client.on('data', (data) => {
  console.log('Received data:', data.toString());
});

client.on('end', () => {
  console.log('Connection closed by server');
});

二、HTTPS 握手过程(四次握手):

HTTPS握手过程在建立安全连接之前需要进行TCP握手来建立基本的网络连接。HTTPS是在HTTP协议上添加了TLS/SSL加密层的协议。TLS/SSL协议需要在TCP连接建立之后才能进行握手过程,确保通信双方建立了安全的加密通道。

过程

  • 第一次握手:客户端向服务器发送一个加密套件列表和一个随机数,请求建立连接。

  • 第二次握手:服务器选择一个加密套件和一个随机数,并发送服务器证书给客户端。

  • 第三次握手:客户端验证服务器证书的合法性,并生成一个用于对称加密的密钥,并将密钥加密后发送给服务器。

  • 第四次握手:服务器解密客户端发送的密钥,并使用该密钥进行加密和解密通信。

在 HTTPS 握手过程中,客户端和服务器之间进行了四次握手,确保建立了安全的加密通道。完成握手后,客户端和服务器可以开始进行加密通信。

示例

下面是一个使用Node.js的示例代码,演示了HTTPS客户端和服务器之间的握手过程:

js 复制代码
// HTTPS服务器代码
const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.crt'),
};

const server = https.createServer(options, (req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, HTTPS!');
});

server.listen(443, () => {
  console.log('HTTPS server listening on port 443');
});

// HTTPS客户端代码
const https = require('https');

const options = {
  hostname: 'localhost',
  port: 443,
  path: '/',
  method: 'GET',
};

const req = https.request(options, (res) => {
  console.log(`Server responded with status code: ${res.statusCode}`);

  res.on('data', (data) => {
    console.log('Received data:', data.toString());
  });
});

req.on('error', (error) => {
  console.error('Request error:', error);
});

req.end();

三、对称加密与非对称加密

因为前面提到加密与解密,所以这里作为补充温故下这两个知识点

1. 对称加密

对称加密使用相同的密钥(称为密钥)来进行加密和解密数据。发送方使用密钥将明文数据加密,接收方使用相同的密钥解密数据。对称加密算法的优势在于处理速度快,适用于大量数据的加密和解密。常见的对称加密算法有AES(高级加密标准)和DES(数据加密标准)等。

下面是一个使用 Node.js 进行对称加密的示例代码:

javascript 复制代码
const crypto = require('crypto');

// 定义密钥和明文数据
const key = 'SecretKey12345678';
const plaintext = 'Sensitive data';

// 创建加密器对象
const cipher = crypto.createCipher('aes-256-cbc', key);

// 加密数据
let encrypted = cipher.update(plaintext, 'utf8', 'hex');
encrypted += cipher.final('hex');

console.log('Encrypted data:', encrypted);

// 创建解密器对象
const decipher = crypto.createDecipher('aes-256-cbc', key);

// 解密数据
let decrypted = decipher.update(encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');

console.log('Decrypted data:', decrypted);

2. 非对称加密

非对称加密使用一对密钥,分别是公钥私钥。发送方使用接收方的公钥加密数据,接收方使用自己的私钥解密数据。非对称加密算法的优势在于提供了更高的安全性,可用于密钥交换和数字签名等场景。常见的非对称加密算法有RSA和ECC等。

下面是一个使用 Node.js 进行非对称加密的示例代码:

javascript 复制代码
const crypto = require('crypto');

// 生成密钥对
const { publicKey, privateKey } = crypto.generateKeyPairSync('rsa', {
  modulusLength: 2048,
});

// 定义明文数据
const plaintext = 'Sensitive data';

// 使用公钥加密数据
const encrypted = crypto.publicEncrypt(publicKey, Buffer.from(plaintext));

console.log('Encrypted data:', encrypted.toString('base64'));

// 使用私钥解密数据
const decrypted = crypto.privateDecrypt(privateKey, encrypted);

console.log('Decrypted data:', decrypted.toString());

注意

HTTPS(安全的超文本传输协议)使用对称加密和非对称加密的混合方式来实现通信的安全性。对称加密算法用于加密和解密实际的数据传输,而非对称加密算法用于安全地交换对称加密所需的密钥。

写在最后

其实TCP 握手和 HTTPS 握手是软件开发者基本都会了解并且在面试中经常会被问到的问题,本文旨在温故而知新,学习的过程是一个反复确认和实践的过程,也是一个需要被记录和可视化的过程,共勉~

相关推荐
丁总学Java9 小时前
微信小程序-npm支持-如何使用npm包
前端·微信小程序·npm·node.js
看到请催我学习12 小时前
如何实现两个标签页之间的通信
javascript·css·typescript·node.js·html5
NiNg_1_23416 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
余生H16 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
Ink17 小时前
从底层看 path.resolve 实现
前端·node.js
奔跑吧邓邓子20 小时前
npm包管理深度探索:从基础到进阶全面教程!
前端·npm·node.js
知否技术1 天前
为什么nodejs成为后端开发者的新宠?
前端·后端·node.js
谢尔登1 天前
【Node.js】worker_threads 多线程
node.js
osnet2 天前
showdoc二次开发
node.js·vue
泯泷2 天前
「生产必看」在企业环境中正确使用 Node.js 的九大原则
前端·后端·node.js