HTTPS 原理

简介: HTTPS是HTTP与SSL/TLS的结合,通过数字证书验证身份,利用非对称加密安全交换会话密钥,再以对称加密高效传输数据。它确保了通信的机密性、完整性和服务器真实性,在互联网上构建安全加密通道。

概述
可以把 HTTPS 理解为 “穿着 SSL/TLS 盔甲的 HTTP”。

它的核心目标很简单:
在不安全的网络(如互联网)上建立一个安全的通信通道,确保数据传输的三大安全属性:

机密性:内容不会被窃听者解密
完整性:内容在传输过程中未被篡改
身份真实性:你连接的服务器就是你以为的那个服务器
一、非对称加密与对称加密的结合
HTTPS 的安全并非依赖单一技术,而是巧妙地结合了两种加密方式。

  1. 对称加密
    Symmetric Encryption

// 示例:AES 对称加密(简化版)
const crypto = require('crypto');

const secretKey = 'my-super-secret-key-32'; // 同一把密钥用于加/解密
const message = "这是要加密的敏感信息";

// 加密
const encrypted = crypto.AES.encrypt(message, secretKey);
console.log("密文:", encrypted); // 输出乱码字符串

// 解密
const decrypted = crypto.AES.decrypt(encrypted, secretKey);
console.log("明文:", decrypted); // 恢复原文
概念:加密和解密使用同一把密钥。
优点:速度快,适合加密大量数据(如网页内容)。
缺点:如何安全地把 secretKey 发送给对方?如果密钥在网络中明文传输,攻击者可截获并解密所有消息。

  1. 非对称加密
    Asymmetric Encryption

// 示例:RSA 非对称加密(Node.js crypto 模拟)
const {
generateKeyPairSync } = require('crypto');

// 生成公钥/私钥对(仅演示用,生产环境需更强参数)
const {
publicKey, privateKey } = generateKeyPairSync('rsa', {

modulusLength: 2048,
});

const data = "只有私钥能解开的信息";

// 客户端用公钥加密
const encryptedData = crypto.publicEncrypt(publicKey, Buffer.from(data));
console.log("公钥加密后:", encryptedData.toString('base64'));

// 服务器用私钥解密
const decryptedData = crypto.privateDecrypt(privateKey, encryptedData);
console.log("私钥解密后:", decryptedData.toString()); // 输出原文
概念:一对密钥 —— 公钥 和 私钥
公钥加密 → 私钥解密(用于保密)
私钥签名 → 公钥验证(用于认证)
优点:解决了密钥分发问题。公钥可公开传播,即使被窃听也无法反向推导出私钥。
缺点:运算慢,不适合频繁加密大块数据。

  1. HTTPS 的智慧:混合加密机制
    用非对称加密交换密钥,用对称加密传输数据

// TLS 握手阶段:客户端生成预主密钥,并用服务器公钥加密发送
let preMasterSecret = generateRandomBytes(48); // 如 48 字节随机数

// 使用从证书中提取的服务器公钥进行加密
let encryptedPreMaster = RSA.encrypt(preMasterSecret, serverPublicKey);

// 发送给服务器
sendToServer('/tls-handshake', {
encryptedPreMaster });

// 后续通信全部使用基于此生成的对称密钥
let sessionKey = deriveSessionKey(clientRandom, serverRandom, preMasterSecret);
useSymmetricEncryption(sessionKey); // 开始 AES 加密通信
最终效果:

初始阶段通过非对称加密安全传递“会话密钥”
后续通信采用高速对称加密(如 AES-GCM),兼顾安全性与性能
二、数字证书(Digital Certificate)

  1. 问题引入
    如何确保你拿到的公钥是真实服务器的,而不是中间人伪造的?

危险场景:

客户端 ──→ 攻击者(伪装成服务器)──→ 真实服务器
↑ 截获并替换公钥 ↑
攻击者用自己的公钥冒充服务器,即可完成“中间人攻击”。

  1. 解决方案:数字证书
    数字证书就像服务器的“网络身份证”,由可信第三方——CA 颁发。

证书的数据结构示例(JSON 形式)
{

"subject": {

"commonName": "www.example.com",
"organization": "Example Inc.",
"country": "US"

},
"issuer": {

"commonName": "DigiCert TLS RSA SHA256 2020 CA1",
"organization": "DigiCert Inc",
"country": "US"

},
"publicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----",
"validFrom": "2025-01-01T00:00:00Z",
"validTo": "2026-01-01T23:59:59Z",
"signatureAlgorithm": "sha256WithRSAEncryption",
"fingerprint": "A1:B2:C3:D4:E5:F6:78:90...",
"extensions": [
{
"name": "subjectAltName", "altNames": ["example.com", "*.example.com"] }
],
"caSignature": "3045022100b9d...fcda" // CA 对整个证书内容的数字签名
}
浏览器收到该证书后,会使用内置的 CA 根证书公钥来验证 caSignature 是否有效。

3.信任链机制(Certificate Chain)
// 伪代码:浏览器验证证书流程
function validateCertificate(cert, rootCAs) {

// 1. 检查有效期
if (new Date() < cert.validFrom || new Date() > cert.validTo) {

throw new Error("证书已过期");

}

// 2. 检查域名匹配
if (!cert.extensions.altNames.includes(currentDomain)) {

throw new Error("域名不匹配");

}

// 3. 验证签名:使用签发者(Issuer)的公钥验证签名
const issuerPublicKey = getTrustedCAPublicKey(cert.issuer);
const dataToVerify = serializeWithoutSignature(cert);

if (!RSA.verifySignature(dataToVerify, cert.caSignature, issuerPublicKey)) {

throw new Error("证书签名无效,可能被篡改");

}

console.log(" 证书验证通过!");
return true;
}
若任一检查失败 → 浏览器弹出警告:“您的连接不是私密连接”

三、HTTPS 通信全过程(TLS 握手详解)
这是 HTTPS 安全通信的核心环节。以下每一步都配有模拟代码或数据交互示意。

步骤 1:Client Hello
客户端发起连接请求:

GET / HTTP/1.1
Host: www.example.com
Connection: Upgrade
Upgrade: tls/1.3
同时发送 TLS 层信息(不在 HTTP 头中):

{

"tlsVersion": ["TLSv1.2", "TLSv1.3"],
"cipherSuites": [
"TLS_AES_128_GCM_SHA256",
"TLS_RSA_WITH_AES_256_CBC_SHA"
],
"clientRandom": "a1b2c3d4e5f6...", // 32 字节随机数
"extensions": {

"supported_groups": ["secp256r1", "x25519"],
"signature_algorithms": ["rsa_pkcs1_sha256"]

}
}
这些信息告诉服务器:“我能支持哪些加密方式,请你选一个。”

步骤 2:Server Hello
服务器选择最优配置并回应:

{

"selectedTlsVersion": "TLSv1.3",
"selectedCipherSuite": "TLS_AES_128_GCM_SHA256",
"serverRandom": "f6e5d4c3b2a1...", // 服务器生成的随机数
"certificate": {

"subject": "www.example.com",
"publicKey": "-----BEGIN PUBLIC KEY-----...",
"caSignature": "3045022100b9d..."

}
}
至此,客户端已获得服务器证书和两个随机数。

步骤 3:证书验证
客户端执行自动验证(无需用户干预,除非出错):

try {

verifyCertificate(serverCert);
} catch (error) {

showBrowserWarning(安全警告:${ error.message});
blockPageLoad();
}
常见错误提示:

“此网站的安全证书有问题”
“NET::ERR_CERT_DATE_INVALID”
“无法验证此证书是由受信任的机构颁发的”
步骤 4:生成预主密钥(Pre-Master Secret)
// 客户端行为
const preMasterSecret = generateRandomBytes(48); // 如 ECDHE 中的共享密钥

// 从证书中提取公钥
const serverPublicKey = parsePublicKeyFromCert(serverCert);

// 用公钥加密预主密钥(TLS 1.2 及以前)
const encryptedPreMaster = RSA.encrypt(preMasterSecret, serverPublicKey);

// 发送给服务器
sendEncryptedPreMaster(encryptedPreMaster);
注意:现代 TLS(如 1.3)通常使用 ECDHE 密钥交换,不再需要加密预主密钥,而是通过椭圆曲线计算达成共识,具备前向安全性。

步骤 5:服务器解密预主密钥
// 服务器行为(TLS 1.2)
const encryptedPreMaster = receiveFromClient();

// 使用自己的私钥解密
const preMasterSecret = RSA.decrypt(encryptedPreMaster, privateKey);

if (!preMasterSecret) {

terminateConnection("预主密钥解密失败");
}
私钥始终保存在服务器本地,绝不外泄!

步骤 6:生成会话密钥(Session Key)
双方使用三个随机数生成相同的会话密钥:

// 伪函数:PRF 是伪随机函数(Pseudo-Random Function)
function generateMasterSecret(preMasterSecret, clientRandom, serverRandom) {

return PRF(preMasterSecret, 'master secret', clientRandom + serverRandom, 48);
}

function deriveSessionKey(masterSecret, label = 'key expansion') {

return PRF(masterSecret, label, serverRandom + clientRandom, 32); // 例如 AES-256 密钥
}

// 双方独立计算,结果一致
const masterSecret = generateMasterSecret(preMasterSecret, clientRandom, serverRandom);
const sessionKey = deriveSessionKey(masterSecret);

console.log("🎯 会话密钥生成完成:", sessionKey.toString('hex'));
只要输入相同,输出就相同 —— 这是数学的魅力!

步骤 7:握手完成,开始安全通信
// 客户端发送加密的 Finished 消息
const finishedMessage = "handshake_finished";
const encryptedFinished = AES.encrypt(finishedMessage, sessionKey, iv);

send(encryptedFinished);

// 服务器解密并验证
const received = AES.decrypt(encryptedFinished, sessionKey, iv);
if (received === "handshake_finished") {

sendAck(); // 回应确认
startSecureHTTP(); // 正式进入 HTTPS 通信
}
从此以后:

所有 HTTP 请求和响应都被封装在 TLS 记录层中,经过对称加密传输:

[TLS RECORD LAYER]
Content-Type: ApplicationData
Encrypted Payload: a1b2c3d4e5f6...
四、HTTPS 如同寄密信(带代码类比)
想象你要通过一个不安全的邮递系统(互联网)给朋友(服务器)寄一封密信。

  1. 获取公钥(证书)
    朋友先通过权威公证处(CA)公证了他的公开信箱(公钥),并把公证书寄给你。

// 你收到证书后验证它是否可信
const cert = downloadCertificate("https://friend.com");
validateCertificate(cert, trustedCAList); // 返回 true 表示可信

  1. 传递密钥(握手)
    你写一封信,里面装着一把保险箱的钥匙(会话密钥),然后放进朋友的公开信箱(用公钥加密),寄出去。

const sessionKey = generateSessionKey();
const encryptedKey = RSA.encrypt(sessionKey, friendPublicKey);
mail.send("公开信箱", encryptedKey);
即使信被截获,别人没有朋友的私人钥匙(私钥),也打不开信箱。

  1. 朋友拿到钥匙
    朋友用他的私人钥匙打开信箱,取出保险箱钥匙。

const encryptedKey = mail.receive();
const sessionKey = RSA.decrypt(encryptedKey, friendPrivateKey);
console.log("🔑 会话密钥已就位!");

  1. 安全通信开始
    现在你们都有了同一把保险箱钥匙。之后所有的信件都放进这个保险箱邮寄,既安全又快捷。

// 日常通信
function sendSecureMessage(msg, key) {

const encrypted = AES.encrypt(msg, key);
return transmitOverInternet(encrypted);
}

function readSecureMessage(encryptedMsg, key) {

const plainText = AES.decrypt(encryptedMsg, key);
return plainText;
}
五、关键要点回顾(附代码说明)
要点 说明 关键代码体现
混合加密 非对称加密用于交换密钥,对称加密用于传输数据 RSA.encrypt(preMaster) + AES.encrypt(payload)
数字证书 包含公钥 + CA 签名,防止伪造 verifySignature(cert.data, cert.signature, caPubKey)
TLS 握手 建立安全连接的关键过程 ClientHello → ServerHello → Certificate → PreMaster → SessionKey
三重随机数 客户端随机 + 服务器随机 + 预主密钥 → 唯一会话密钥 PRF(preMaster, randomA + randomB)
前向安全性 即使未来私钥泄露,也无法解密过去的通信 使用 ECDHE 密钥交换,每次会话密钥独立
现代 TLS 1.3 已默认启用前向安全性,废弃静态 RSA 密钥交换。

六、总结
HTTPS 并不是一种全新的协议,而是 HTTP + TLS/SSL 的安全组合。

它通过:

数字证书验证身份( 我连的是真的银行网站)
非对称加密建立信任( 安全传递密钥)
对称加密保障性能( 快速加密网页内容)
在开放网络中构建出一条“加密隧道”,让我们可以安全地浏览网页、登录账号、进行支付。

下次当你看到浏览器地址栏的小锁图标时,就知道:
背后正有一场精密而优雅的加密握手在悄然完成。

本文参考 TLS 1.2/1.3 协议设计原理,结合 Node.js crypto API 风格编写示例代码,旨在帮助初学者理解 HTTPS 底层机制。实际实现涉及 C/C++ 和底层协议栈,此处为高度简化模型。

相关文章
|
13天前
|
数据采集 人工智能 安全
|
8天前
|
编解码 人工智能 自然语言处理
⚽阿里云百炼通义万相 2.6 视频生成玩法手册
通义万相Wan 2.6是全球首个支持角色扮演的AI视频生成模型,可基于参考视频形象与音色生成多角色合拍、多镜头叙事的15秒长视频,实现声画同步、智能分镜,适用于影视创作、营销展示等场景。
652 4
|
8天前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:七十、小树成林,聚沙成塔:随机森林与大模型的协同进化
随机森林是一种基于决策树的集成学习算法,通过构建多棵决策树并结合它们的预测结果来提高准确性和稳定性。其核心思想包括两个随机性:Bootstrap采样(每棵树使用不同的训练子集)和特征随机选择(每棵树分裂时只考虑部分特征)。这种方法能有效处理大规模高维数据,避免过拟合,并评估特征重要性。随机森林的超参数如树的数量、最大深度等可通过网格搜索优化。该算法兼具强大预测能力和工程化优势,是机器学习中的常用基础模型。
350 164
|
7天前
|
机器学习/深度学习 自然语言处理 机器人
阿里云百炼大模型赋能|打造企业级电话智能体与智能呼叫中心完整方案
畅信达基于阿里云百炼大模型推出MVB2000V5智能呼叫中心方案,融合LLM与MRCP+WebSocket技术,实现语音识别率超95%、低延迟交互。通过电话智能体与座席助手协同,自动化处理80%咨询,降本增效显著,适配金融、电商、医疗等多行业场景。
359 155