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

相关推荐
小纯洁w2 小时前
Webpack 的 require.context 和 Vite 的 import.meta.glob 的详细介绍和使用
前端·webpack·node.js
熬夜不洗澡3 小时前
Node.js中不支持require和import两种导入模块的混用
node.js
bubusa~>_<3 小时前
解决npm install 出现error,比如:ERR_SSL_CIPHER_OPERATION_FAILED
前端·npm·node.js
天下皆白_唯我独黑5 小时前
npm 安装扩展遇到证书失效解决方案
前端·npm·node.js
~欸嘿5 小时前
Could not download npm for node v14.21.3(nvm无法下载节点v14.21.3的npm)
前端·npm·node.js
融化的雪6 小时前
nodejs npm install、npm run dev运行的坎坷之路
node.js
林的快手8 小时前
CSS文本属性
前端·javascript·css·chrome·node.js·css3·html5
海盗强9 小时前
Webpack打包优化
前端·webpack·node.js
^^为欢几何^^9 小时前
npm、pnpm和yarn有什么区别
前端·npm·node.js
程楠楠&M10 小时前
uni-app(位置1)
前端·javascript·uni-app·node.js