这是一篇信息整理文章,可以当作工具来看
HTTP全称是超文本传输协议,构建于TCP之上,属于应用层协议。
http通信有什么问题?
## 1.1 可能被窃听
- HTTP 本身不具备加密的功能,HTTP 报文使用明文方式发送
- 由于互联网是由联通世界各个地方的网络设施组成,所有发送和接收经过某些设备的数据都可能被截获或窥视。(例如大家都熟悉的抓包工具:Wireshark),即使经过加密处理,也会被窥视是通信内容,只是可能很难或者无法破解出报文的信息而已
1.2 认证问题
- 无法确认你发送到的服务器就是真正的目标服务器(可能服务器是伪装的)
- 无法确定返回的客户端是否是按照真实意图接收的客户端(可能是伪装的客户端)
- 无法确定正在通信的对方是否具备访问权限,Web 服务器上某些重要的信息,只想发给特定用户即使是无意义的请求也会照单全收。无法阻止海量请求下的 DoS 攻击(Denial of Service,拒绝服务攻击)。
1.3 可能被篡改
请求或响应在传输途中,遭攻击者拦截并篡改内容的攻击被称为中间人攻击(Man-in-the-Middle attack,MITM)
HTTPS如何解决上述三个问题
HTTPS是在通信接口部分用 TLS(Transport Layer Security)协议。
SSL 和 TLS 的区别
- 传输层安全性协议(英语:Transport Layer Security,缩写作 TLS),及其前身安全套接层(Secure Sockets Layer,缩写作 SSL)是一种安全协议,目的是为互联网通信,提供安全及数据完整性保障。
- 网景公司(Netscape)在1994年推出首版网页浏览器,网景导航者时,推出HTTPS协议,以SSL进行加密,这是SSL的起源。
- IETF将SSL进行标准化,1999年公布第一版TLS标准文件。随后又公布RFC 5246 (2008年8月)与 RFC 6176 (2011年3月)。以下就简称SSL
- TLS是SSL的标准. HTTPS 就是 HTTP + SSL
# SSL 协议
HTTPS 协议的主要功能基本都依赖于 TLS/SSL 协议,TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
1.1 对称加密
- 常见的有 AES-CBC、DES、3DES、AES-GCM等,相同的密钥可以用于信息的加密和解密,掌握密钥才能获取信息,能够防止信息窃听,通信方式是1对1;
- 对称加密需要共享相同的密码,密码的安全是保证信息安全的基础,服务器和多 个客户端通信,需要维持多个密码记录,且缺少修改密码的机制;
- 优点:算法公开、计算量小、加密速度快、加密效率高。
- 缺点:交易双方都使用同样钥匙,安全性得不到保证。
1.2 非对称加密技术
- 即常见的 RSA 算法,还包括 ECC、DH 等算法,算法特点是,密钥成对出现,一般称为公钥(公开)和私钥(保密),公钥加密的信息只能私钥解开,私钥加密的信息只能公钥解开。因此掌握公钥的不同客户端之间不能互相解密信息,只能和掌握私钥的服务器进行加密通信,服务器可以实现1对多的通信,客户端也可以用来验证掌握私钥的服务器身份。
- 非对称加密的特点是信息传输一对多,服务器只需要维持一个私钥就能够和多个客户端进行加密通信,但服务器发出的信息能够被所有的客户端解密,且该算法的计算复杂,加密速度慢。
1.3 完整性验证算法
- 常见的有 MD5、SHA1、SHA256,该类函数特点是函数单向不可逆、对输入非常敏感、输出长度固定,针对数据的任何修改都会改变散列函数的结果,用于防止信息篡改并验证数据的完整性;
- 在信息传输过程中,散列函数不能单独实现信息防篡改,因为明文传输,中间人可以修改信息之后重新计算信息摘要,因此需要对传输的信息以及信息摘要进行加密;
1.4 工作方式
结合三类算法的特点,TLS 的基本工作方式是
- 客户端使用非对称加密与服务器进行通信,实现身份验证并协商对称加密使用的密钥
- 然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信,不同的节点之间采用的对称密钥不同,从而可以保证信息只能通信双方获取。
1.5 SSL协议构成
- 第一层是记录协议(Record Protocol), 用于定义传输格式。
- 第二层握手协议(Handshake Protocol),它建立在SSL记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等。
https服务器
在创业HTTPS服务器之前,服务器首先需要创建公钥、私钥及证书,步骤如下
2.1 创建私钥
openssl genrsa -out privatekey.pem 1024
2.2 创建证书签名请求(Certificate Signing Request)文件
openssl req -new -key privatekey.pem -out certrequest.csr
2.3 获取证书
证书应该是一个经过证书授证中心签名的文件,该证书文件内包含了服务器端提供的公钥以及证书的办法机构等信息。
openssl x509 -req -in certrequest.csr -signkey privatekey.pem -out certificate.pem
2.4 获取证书
在具备了证书文件后,可以使用该证书文件创建一个pfx文件。 所谓pfx文件,是指该文件内容必须符合公钥加密技术12号标准。
openssl pkcs12 -export -in certificate.pem -inkey privatekey.pem -out certificate.pfx
2.5 创建服务器
https.createServer(options,[requestListener]);
- pfx 私钥、公钥以及证书
- key 私钥
- passphrase 为私钥指定密码
- cert 公钥
- ca 证书,用于指定一组证书,默认属性值为几个著名的证书授权中心,例如VerlSign
- crl 指定证书吊销主
let https = require('https');
let fs = require('fs');
let path = require('path');
let key = fs.readFileSync(path.join(__dirname, 'privatekey.pem'));
let cert = fs.readFileSync(path.join(__dirname, 'certificate.pem'));
let opts = {
key,
cert
};
let server = https.createServer(opts, function (req, res) {
console.log(req.url);
if (req.url != '/favicon.ico') {
res.setHeader('Content-Type', 'text/html');
res.write(`<html><head><meta charset="utf8"/></head><body>hello</body></html>`);
res.end();
}
});
server.listen(443, function () {
console.log('服务器端开始监听!');
//server.close();
});
server.on('close', function () {
console.log('服务器已被关闭!');
});
2.6 创建HTTPS客户端
在https模块中,可以使用request方法向其它使用HTTPS协议的网站请求数据
let req = https.request(options,callback);
- host 指定域名或目标主机的IP地址
- hostname 指定域名或目标主机的IP地址
- port 端口号
- method 指定请求方法名
- path 指下请求路径及查询字符串
- headers 客户端请求头对象
- auth 指定认证信息部分
- agent 指定用户代理,指定false则从连接池中挑选一个连接状态为关闭的https.Agent对象
- pfx 指定私钥、公钥和证书
- key 指定私钥
- cert 公钥
- ca 一组证书
let https = require('https');
process.env.NODE_TLS_REJECT_UNAUTHORIZED = "0"
let options = {
hostname: '123.57.77.210',
port: 443,
path: '/',
method: 'GET',
agent: false
}
let req = https.request(options, function (res) {
console.log(res.statusCode);
console.log(res.headers);
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log(chunk);
});
});
req.end();
HTTP
- 请求的一方叫客户端,响应的一方叫服务器端
- 通过请求和响应达成通信
- HTTP是一种不保存状态的协议
3.1 内容协商
首部字段
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
协商类型
- 服务器驱动
- 客户端驱动协商
- 透明协商
3.2 状态码
状态码负责表示客户端请求的返回结果、标记服务器端是否正常、通知出现的错误
3.3 状态码类别
类别 原因短语
- 1XX Informational(信息性状态码)
- 2XX Success(成功状态码)
- 3XX Redirection(重定向)
- 4XX Client Error(客户端错误状态码)
- 5XX Server Error(服务器错误状态吗)
3.4.1 2XX 成功
- 200(OK 客户端发过来的数据被正常处理
- 204(Not Content 正常响应,没有实体
- 206(Partial Content 范围请求,返回部分数据,响应报文中由Content-Range指定实体内容
3.4.2 3XX 重定向
- 301(Moved Permanently) 永久重定向
- 302(Found) 临时重定向,规范要求方法名不变,但是都会改变
- 303(See Other) 和302类似,但必须用GET方法
- 304(Not Modified) 状态未改变 配合(If-Match、If-Modified-Since、If-None_Match、If-Range、If-Unmodified-Since)
- 307(Temporary Redirect) 临时重定向,不该改变请求方法
3.4.3 4XX 客户端错误
- 400(Bad Request) 请求报文语法错误
- 401 (unauthorized) 需要认证
- 403(Forbidden) 服务器拒绝访问对应的资源
- 404(Not Found) 服务器上无法找到资源
3.4.4 5XX 服务器端错误
- 500(Internal Server Error)服务器故障
- 503(Service Unavailable) 服务器处于超负载或正在停机维护
首部
4.1 通用首部字段
| 首部字段名 | 说明 |
| - | :-: | -: |
Cache-Control | 控制缓存行为
Connection | 链接的管理
Date | 报文日期
Pragma | 报文指令
Trailer | 报文尾部的首部
Trasfer-Encoding | 指定报文主体的传输编码方式
Upgrade | 升级为其他协议
Via | 代理服务器信息
Warning | 错误通知
4.2 请求首部字段
| 首部字段名 | 说明 |
| - | :-: | -: |
Accept | 用户代理可处理的媒体类型
Accept-Charset | 优先的字符集
Accept-Encoding | 优先的编码
Accept-Langulage | 优先的语言
Authorization | Web认证信息
Expect | 期待服务器的特定行为
From | 用户的电子邮箱地址
Host | 请求资源所在的服务器
If-Match | 比较实体标记
If-Modified-Since | 比较资源的更新时间
If-None-Match | 比较实体标记
If-Range | 资源未更新时发送实体Byte的范围请求
If-Unmodified-Since | 比较资源的更新时间(和If-Modified-Since相反)
Max-Forwards | 最大传输跳数
Proxy-Authorization | 代理服务器需要客户端认证
Range | 实体字节范围请求
Referer | 请求中的URI的原始获取方
TE | 传输编码的优先级
User-Agent | HTTP客户端程序的信息
4.3 响应首部字段
| 首部字段名 | 说明 |
| - | :-: | -: |
Accept-Ranges | 是否接受字节范围
Age | 资源的创建时间
ETag | 资源的匹配信息
Location | 客户端重定向至指定的URI
Proxy-Authenticate | 代理服务器对客户端的认证信息
Retry-After | 再次发送请求的时机
Server | 服务器的信息
Vary | 代理服务器缓存的管理信息
www-Authenticate | 服务器对客户端的认证
4.4 实体首部字段
| 首部字段名 | 说明 |
| - | :-: | -: |
Allow | 资源可支持的HTTP方法
Content-Encoding | 实体的编码方式
Content-Language | 实体的自然语言
Content-Length | 实体的内容大小(字节为单位)
Content-Location | 替代对应资源的URI
Content-MD5 | 实体的报文摘要
Content-Range | 实体的位置范围
Content-Type | 实体主体的媒体类型
Expires | 实体过期时间
Last-Modified | 资源的最后修改时间
这些信息头是做压缩,缓存,范围请求等功能的必需条件,想了解的可以看看我写的静态服务。