面试题答案
一键面试HTTPS加密原理
- 对称加密:
- 原理:使用同一个密钥进行加密和解密。发送方用密钥对数据加密,接收方用相同密钥解密。例如常见的AES(高级加密标准)算法。它的优点是加密和解密速度快,适合大量数据传输。但缺点是密钥管理困难,因为通信双方需要共享密钥,如果密钥在传输过程中被截取,数据就会被破解。
- 非对称加密:
- 原理:有公钥和私钥一对密钥。公钥可以公开,任何人都能用公钥加密数据,只有拥有私钥的一方才能解密。例如RSA算法。它解决了对称加密中密钥传输的安全问题,但加密和解密速度比对称加密慢。
- 数字证书的作用:
- 身份验证:数字证书由受信任的证书颁发机构(CA)颁发,包含网站的域名、公钥等信息。当客户端向服务器请求建立HTTPS连接时,服务器会将数字证书发送给客户端。客户端通过验证证书的合法性(如证书是否由受信任的CA颁发、是否过期等)来确认服务器的真实身份,防止中间人攻击。
- 绑定公钥:证书将服务器的公钥与服务器身份绑定,确保客户端使用的公钥确实属于该服务器,而不是被中间人替换的公钥。
HTTPS通信性能优化思路
- 减少握手延迟:
- 会话复用:HTTPS连接建立后,客户端和服务器可以协商一个会话ID,后续的连接可以重用这个会话ID,减少握手过程。在Node.js中,
https.Server
对象的createSecureContext
方法可以配置sessionIdContext
选项来启用会话复用。 - TLS 1.3优化:TLS 1.3减少了握手的往返次数,从TLS 1.2的3次往返减少到1次往返(或0 - RTT,即0次往返,如果会话复用成功)。在Node.js中,使用Node.js v12及以上版本,默认支持TLS 1.3,应用层不需要额外配置来启用TLS 1.3的基本优化特性。
- 会话复用:HTTPS连接建立后,客户端和服务器可以协商一个会话ID,后续的连接可以重用这个会话ID,减少握手过程。在Node.js中,
- 优化证书验证:
- 缓存证书验证结果:对于经常访问的网站,可以缓存证书验证结果,避免每次连接都进行完整的证书验证流程。在Node.js中,可以通过自定义证书验证逻辑实现,例如使用
https.request
的rejectUnauthorized
选项为false
(不推荐在生产环境中直接使用,因为会绕过证书验证,增加安全风险),然后自己实现证书缓存和验证逻辑。
- 缓存证书验证结果:对于经常访问的网站,可以缓存证书验证结果,避免每次连接都进行完整的证书验证流程。在Node.js中,可以通过自定义证书验证逻辑实现,例如使用
- 内容压缩:
- 启用HTTP压缩:在服务器端启用内容压缩,可以减少数据传输量,提高传输速度。在Node.js中,可以使用
compression
中间件,例如在Express应用中:
- 启用HTTP压缩:在服务器端启用内容压缩,可以减少数据传输量,提高传输速度。在Node.js中,可以使用
const express = require('express');
const compression = require('compression');
const app = express();
app.use(compression());
// 其他路由和中间件配置
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem')
};
https.createServer(options, app).listen(443, () => {
console.log('HTTPS server running on port 443');
});
相关Node.js代码示例
以下是一个简单的Node.js HTTPS服务器示例,包含启用会话复用:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('privatekey.pem'),
cert: fs.readFileSync('certificate.pem'),
sessionIdContext: 'unique_context' // 启用会话复用
};
const server = https.createServer(options, (req, res) => {
res.writeHead(200);
res.end('Hello, HTTPS!\n');
});
server.listen(443, () => {
console.log('HTTPS server running on port 443');
});