HTTPS通信过程
HTTPS通信过程
HTTPS协议 = HTTP协议 + SSL/TLS协议,在HTTPS数据传输的过程中,需要用SSL/TLS对数据进行加密和解密,需要用HTTP对加密后的数据进行传输,由此可以看出HTTPS是由HTTP和SSL/TLS一起合作完成的。
SSL的全称是Secure Sockets Layer,即安全套接层协议,是为网络通信提供安全及数据完整性的一种安全协议。SSL协议在1994年被Netscape发明,后来各个浏览器均支持SSL,其最新的版本是3.0
TLS的全称是Transport Layer Security,即安全传输层协议,最新版本的TLS(Transport Layer Security,传输层安全协议)是IETF(Internet Engineering Task Force,Internet工程任务组)制定的一种新的协议,它建立在SSL 3.0协议规范之上,是SSL 3.0的后续版本。在TLS与SSL3.0之间存在着显著的差别,主要是它们所支持的加密算法不同,所以TLS与SSL3.0不能互操作。虽然TLS与SSL3.0在加密算法上不同,但是在我们理解HTTPS的过程中,我们可以把SSL和TLS看做是同一个协议。
HTTPS为了兼顾安全与效率,同时使用了对称加密和非对称加密。数据是被对称加密传输的,对称加密过程需要客户端的一个密钥,为了确保能把该密钥安全传输到服务器端,采用非对称加密对该密钥进行加密传输,总的来说,对数据进行对称加密,对称加密所要使用的密钥通过非对称加密传输。
下面我们模仿HTTPS的模式实现前后端加解密。
这里非对称加密算法我们选择使用RSA
,对称加密使用AES
:
- 服务端生成非对称加密(RSA)的一对公钥私钥,并将公钥(publicKey)发送给客户端。
- 客户端生成对称加密(AES)密钥(secretKey),并用服务端发送的公钥(publicKey)使用RSA算法加密,将其发送给服务端
- 服务端接收到密文后,用RSA私钥(privateKey)解密,得到对称加密(AES)密钥(secretKey)。
此时,服务端、客户端同时拥有该密钥,使用对称加密(AES)加密解密消息体。
Web端实现
这里我们使用client-crypto
来实现加解密。
Install
npm install client-crypto
Usage
RSA
加密
import Crypto from 'client-crypto';
Crypto.RSA.encrypt('secretKey', 'publicKey');
解密
import Crypto from 'client-crypto';
Crypto.RSA.encrypt('encryptedKey', 'privateKey');
AES
默认使用gcm
模式。
createKey 生成密钥
import Crypto from 'client-crypto';
Crypto.AES.createKey();
使用该方法生成密钥后,会缓存该密钥,使用加密(encrypt)或解密(decrypt)方法时也可不提供密钥。
encrypt 加密
import Crypto from 'client-crypto';
Crypto.AES.encrypt(data, '密钥');
该方法会先执行JSON.stringify(data),将数据转为json格式的字符串,然后使用AES加密。
decrypt 解密
import Crypto from 'client-crypto';
Crypto.AES.decrypt('encrypted message', '密钥');
该方法会使用AES解密,再执行JSON.parse,获取数据。
服务端
RSA
这里我们使用NodeJs作为服务端示例。
可以使用node-rsa
Install
npm install node-rsa
生成密钥
import * as RSA from 'node-rsa';
const rsaKey = new RSA({ b: 512 });
rsaKey.setOptions({
encryptionScheme: 'pkcs1'
});
// 公钥 - 用来发送给客户端
const PUBLIC_KEY = Buffer.from(rsaKey.exportKey('pkcs8-public-der')).toString('base64');
解密
const secretKey = rsaKey.decrypt('密钥加密密文', 'utf8');
AES
服务端的AES实现可参考 AES对称加解密