# HTTP

# 什么是HTTP

  • HTTP(Hyper Text Transfer Protocol), 超文本传输协议,是一个简单的请求-响应协议,通常运行在TCP之上。
  • 请求和响应消息的头部信息,以ASCII编码形式给出;
  • 消息内容,具有一个类似MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展类型,设定某种扩展名的文件,用一种应用程序来打开的方式类型,当该扩展名文件被访问时,浏览器会自动使用指定应用程序来打开)的格式;

# HTTP的发展

  • 0.9协议,是一个交换信息的无序协议,仅仅限于文字传输,远不能满足日益发展的各种需要。
  • 1.0协议,1982年由 Tim Berners-Lee提出 HTTP/1.0;该协议对每一次请求/响应建立并拆除一次连接;
  • 1.1协议,更多的考虑的是速度和效率;
  • 2.0协议,2013年提出,由于网络基础设施更新缓慢,将长期与HTTP1.0,HTTP1.1长期共存;

# 工作原理

  • HTTP是无状态协议,HTTP协议是基于B/S架构,一个服务器可能需要处理成千上万的客户端请求,且服务器只能提供有限个连接,因此HTTP连接是一种一次性连接,用完即释放;
  • 本质上来说,HTTP协议是在TCP的基础上,人为定义的数据流规则,不应从传输层层面去理解HTTP。它核心的功能在于完成获取资源这件事,而非通信。
  • 考虑到效率的问题,HTTP1.1允许连接用于多个请求,连接具有活动机制;

# 报文格式

  • 请求报文:
    • 请求行 -- 通用信息头 -- 请求头 -- 实体头 -- 报文主体
    • 请求行 以请求方法开头,定义了9种,常见的由 GET,POST。
  • 响应报文:
    • 状态行 -- 通用信息头 -- 响应头 -- 实体头 -- 报文主体

# HTTPS

# 什么是HTTPS

  • HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer,超文本传输安全协议),以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。
  • HTTP在HTTP与TCP之间,加入了SSL/TLS(加密/身份验证层)
  • 本质上,HTTPS的改进点在于创造性的使用了非对称加密算法,在不安全的网路上,安全的传输了用来继续宁堆成加密的密钥,综合利用了非对称加密的安全性和对称加密的快速性

# HTTP的固有缺陷

  • 数据明文传送
  • 缺乏数据完整性检验机制,包含两方面内容,一是数据长度,这个已经具备;另一个方面是 内容是否被篡改.

# HTTPS协议的改进

  • 双向身份认证
    • 客户端发起 SSL握手消息给服务端,要求连接
    • 服务端将证书发送给客户端
    • 客户端检查服务端证书,确认是否由自己信任的证书签发机构所签发。如果不是,将是否继续通讯的决定权交给用户选择(这里是一个安全缺陷)。 如果检查无误,活着用户选择继续,则客户端认可服务端的身份。
    • 服务端要求客户端发送证书,并检查是否通过验证。失败则关闭连接,成功则从客户端证书中获取公钥。
  • 数据传输的机密性
    • 客户端和服务端在开始传输数据之前,会协商传输过程需要使用的加密算法。
    • 其中有一个很重要过程: 使用非对称加密算法确保 对称加密的密钥 的安全性
  • 防止重放攻击
    • SSL使用序列号来保护通讯方免受报文重放攻击。

# HTTPS的缺点

  • 相同网络环境下,HTTPS协议会使页面加载时间,延长近50%,增加10%到20%的电耗
  • HTTPS的安全是有范围的,在黑客攻击、拒绝服务攻击和服务器劫持等方面,几乎起不到什么作用
  • SSL证书的信用连体系不安全,某些国家可以控制CA根证书的情况下,中间人攻击一样可行
  • 成本增加,在大规模用户访问的场景下,几乎每一个字节都要做加解密,这就产生了服务器成本

# 在Nginx部署HTTPS服务

# 下载证书到本地

  • 需要经过CA机构签发的SSL证书。 本地证书文件

# 在nginx服务器上安装证书

  • 本质上也就是修改配置,如下示例:

user  root;
worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;

    keepalive_timeout  65;
    server {
        listen       80;
        server_name  www.automannn.cn;
        rewrite ^(.*)$ https://$host$1;

        location / {
            root   html;
            index  index.html index.htm;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }

    server {
        listen       443 ssl;
        server_name  www.automannn.cn;  


        ssl_certificate      /cert/7929866_www.automannn.cn.pem;
        ssl_certificate_key  /cert/7929866_www.automannn.cn.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;

        location / {
           rewrite ^/(.*)$ https://www.automannn.cn/blog;
        }
    }

}

# tomcat部署https服务

  1. 将解压后的证书文件和密码文件上传到Tomcat服务器的conf目录。
  2. 进入Tomcat安装根目录,执行以下命令,打开server.xml文件。
vim ./conf/server.xml 

# tomcat7配置pfx格式证书

<!-- #port属性根据实际情况修改(HTTPS默认端口为443)。如果使用其他端口号,则您需要使用https://domain_name:port的方式来访问您的网站。 
keystoreFile值需替换为证书的实际路径。
keystorePass值需替换为证书密码文件pfx-password.txt中的内容。
如需了解其他配置项,请前往Tomcat官网查看。-->
<Connector port="443"
           protocol="HTTP/1.1"
           SSLEnabled="true"
           scheme="https"
           secure="true"
           keystoreFile="conf/domain_name.pfx"
           keystoreType="PKCS12"
           keystorePass="证书密码"
           clientAuth="false"
           SSLProtocol="TLSv1.1+TLSv1.2+TLSv1.3"
           ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256"/>

# tomcat7配置jks格式证书

<!-- #port属性根据实际情况修改(HTTPS默认端口为443)。如果使用其他端口号,则您需要使用https://domain_name:port的方式来访问您的网站。 
keystoreFile值需替换为证书的实际路径。
keystorePass值需替换为证书密码文件jks-password.txt中的内容。
如需了解其他配置项,请前往Tomcat官网查看。-->
<Connector port="443"
           protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectport="8443"
           maxParameterCount="1000"
           SSLEnabled="true"
           scheme="https"
           secure="true"
           keystoreFile="conf/domain_name.jks"
           keystoreType="JKS"
           keystorePass="证书密码"
           clientAuth="false"
           SSLProtocol="TLSv1.1+TLSv1.2+TLSv1.3"
           ciphers="TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_128_CBC_SHA256,TLS_RSA_WITH_AES_256_CBC_SHA256"/>    

# tomcat8.5及以上配置pfx格式证书

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true"
           maxParameterCount="1000">
    <SSLHostConfig>
        <!-- conf/domain_name.pfx请您替换为证书的实际路径,证书密码替换为证书密码文件pfx-password.txt中的内容 -->
        <Certificate certificateKeystoreFile="conf/domain_name.pfx"
                     certificateKeystorePassword="证书密码"
                     type="RSA"/>
    </SSLHostConfig>
</Connector>

# tomcat8.5及以上配置jks格式证书

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true"
           maxParameterCount="1000">
    <SSLHostConfig>
        <!-- conf/domain_name.jks请您替换为证书的实际路径,证书密码替换为证书密码文件jks-password.txt中的内容 -->
        <Certificate certificateKeystoreFile="conf/domain_name.jks"
                     certificateKeystorePassword="证书密码"
                     type="RSA"/>
    </SSLHostConfig>
</Connector>

# FatJar部署https服务

# 配置密钥信息-application.yml

server:
  port: 8443 # HTTPS默认端口
  ssl:
    key-store: classpath:keystore.jks # JKS文件路径
    key-store-password: yourKeystorePassword # 密钥库密码
    key-password: yourKeyPassword # 私钥密码
    key-alias: mydomain # 别名
    key-store-type: JKS # 密钥库类型,默认为JKS,可以省略

# 自签证书与CA机构证书


# 一、OpenSSL自签证书与CA机构证书的区别

特性 OpenSSL自签证书 CA机构证书
颁发者 用户自己生成,自行签名 由受信任的第三方证书颁发机构(CA)签发
信任链 无信任链,直接自签 包含完整的信任链(根CA → 中间CA → 服务器证书)
浏览器信任 默认不信任,需手动添加例外或导入根证书 自动信任(浏览器/操作系统内置了CA的根证书)
安全性验证 未验证域名或组织身份,仅本地生成 CA会验证域名所有权(DV证书)或组织真实性(OV/EV证书)
适用场景 内部测试、开发环境 生产环境、公开网站
成本 免费 通常需要付费(DV证书有免费选项如Let's Encrypt)

# 二、为什么Linux上自签证书无法被正常访问?

  1. 信任链缺失

    • 浏览器和操作系统维护一个受信任的根证书列表,而自签证书的根证书(即自签的CA)未被加入该列表,导致客户端无法验证其合法性。
  2. 证书验证失败

    • 在HTTPS握手过程中,客户端会检查证书的颁发机构是否受信任、证书是否过期、域名是否匹配等。自签证书因缺乏受信任的CA签名,触发安全警告或直接阻断连接。
  3. 手动信任的局限性

    • 用户可手动将自签证书添加到系统信任库(如Linux的/etc/ssl/certs或浏览器的例外列表),但此操作繁琐且不适合大规模使用,仅限内部测试。

# 三、HTTPS访问流程详解

  1. TCP三次握手

    • 客户端与服务器建立TCP连接(默认端口443)。
  2. TLS握手(核心步骤)

    • Client Hello:客户端发送支持的TLS版本、加密套件列表、随机数(Client Random)。
    • Server Hello:服务器选择加密套件,返回证书、随机数(Server Random)。
    • 证书验证
      • 客户端检查证书是否由受信任的CA签发、域名是否匹配、是否在有效期内。
      • 自签证书在此步骤失败(若未手动信任)。
    • 密钥交换:客户端生成预主密钥(Pre-Master Secret),用服务器证书的公钥加密后发送。
    • 生成会话密钥:双方基于Client Random、Server Random和Pre-Master Secret生成对称加密密钥(Session Key)。
  3. 加密通信

    • 使用对称加密(如AES)传输HTTP数据,保证数据机密性和完整性。

# 四、自签证书的典型错误场景

  • 浏览器警告: 提示“您的连接不是私密连接”或“NET::ERR_CERT_AUTHORITY_INVALID”。

  • CURL访问失败

    curl https://self-signed-site.com
    # 报错:SSL certificate problem: self-signed certificate
    

    解决方法:添加-k参数跳过验证(不推荐)或手动指定证书:

    curl --cacert /path/to/self-signed.crt https://self-signed-site.com
    

# 五、如何正确使用自签证书?

  1. 内部测试环境

    • 将自签的根证书导入客户端系统或浏览器的信任库:
      # Linux系统(以Debian为例)
      sudo cp self-signed.crt /usr/local/share/ca-certificates/
      sudo update-ca-certificates
      
  2. 生产环境替代方案

    • 使用免费CA(如Let's Encrypt)签发受信任的证书:
      certbot --nginx -d example.com
      

# 总结

  • 自签证书:适合本地开发,但需手动信任,存在安全风险。
  • CA证书:由受信任的第三方验证,自动被浏览器信任,适合生产环境。
  • HTTPS流程:依赖TLS握手建立加密通道,核心是证书验证和密钥交换。

# 常见的受信任根证书颁发机构

浏览器的内置受信任的根证书列表是一个预置的权威证书集合,用于验证网站SSL/TLS证书的合法性。这些根证书由国际公认的证书颁发机构(CA)签发,浏览器厂商会根据安全标准和审核流程选择并维护这些信任列表。以下是全球主流浏览器(如Chrome、Firefox、Safari、Edge)和操作系统默认信任的部分根CA:

CA名称 典型用途 示例根证书
DigiCert 广泛用于商业网站、企业服务 DigiCert Global Root CA
Let's Encrypt 免费自动化证书(DV证书) ISRG Root X1
GlobalSign 公共网站、物联网设备 GlobalSign Root CA
Sectigo (原Comodo) 商业SSL证书、代码签名 Sectigo RSA Certification Authority
Entrust 政府、金融领域 Entrust Root Certification Authority
GoDaddy 中小型网站托管 Go Daddy Root Certificate Authority
Microsoft Azure服务、企业内网 Microsoft RSA Root Certificate Authority 2017
Amazon AWS云服务 Amazon Root CA 1
Apple iOS/macOS生态系统 Apple Root CA
瑞士SwissSign 欧洲企业、隐私敏感场景 SwissSign Gold CA - G2

# 根证书列表的来源与管理

  1. 操作系统信任库

    • Windows:通过certmgr.msc管理,根证书存储在Trusted Root Certification Authorities
    • Linux:通常位于/etc/ssl/certs(如Debian/Ubuntu)。
    • macOS:通过钥匙串访问(Keychain Access)的“系统根证书”管理。
  2. 浏览器内置信任库

    • Chrome:依赖操作系统的根证书列表(Windows/Linux)或自有列表(macOS)。
    • Firefox:维护独立的根证书库,与操作系统分离。
    • Safari/Edge:依赖操作系统信任库。

# 如何查看浏览器的根证书列表?

Chrome浏览器为例:

  1. 访问 chrome://settings/security
  2. 点击 “管理证书”“受信任的根证书颁发机构” 标签页。
  3. 可查看所有预置的根证书(如VeriSign、GeoTrust等)。

Firefox为例:

  1. 访问 about:preferences#privacy
  2. 滚动到底部,点击 “证书”“查看证书”“证书颁发机构” 标签页。

# 根证书的动态更新

  1. 自动更新

    • 浏览器和操作系统会定期通过安全更新添加或移除根证书。
    • 例如:当某个CA发生安全事件(如Symantec CA被逐步淘汰),浏览器会将其从信任列表中移除。
  2. 手动管理

    • 用户可手动导入/导出根证书(如企业内网私有CA),但需谨慎操作以避免安全风险。

# 自签证书的流程

# 生成ca证书

#生成一个3072位的Key
openssl genrsa -out ca.key 3072

# -new 表示生成一个新的证书请求
# -x509 表述输出一个x509证书, 而不是证书签名请求
# -days 表示证书的有效期,单位为天
openssl req -new -x509 -days 3650 -key ca.key -out ca.pem
# 依次填写 国家、省、市、地址、组织、组织单位、Common Name,邮箱

# 生成域名证书

# 生成一个 3072位的key(私钥)
openssl genrsa -out harbor.key  3072

#生成一个证书请求,用于签发证书
openssl req -new -key harbor.key -out harbor.csr
#依次填写 国家、省、市、组织、组织单位、域名,邮箱

# 签发证书

openssl x509 -req -in harbor.csr -CA ca.pem -CAkey ca.key -CAcreateserial -out harbor.pem -days 3650

# 使用证书

  • harbor.pem 以及 harbor.key 复制到对应位置即可;
  • 常见服务器类型及证书格式
服务器类型 证书格式 备注
Nginx pem/key 常用于静态网站
Tomcat pfx -
Apache crt/key -
IIS pfx -
JKS jks -
其他 pem/key -
  • 注意,pfx证书与jks证书也有key

# 客户端导入根证书

  • 浏览器导入根证书: chrome://settings/certificates, 管理证书 - 管理从windows导入的证书- 导入 - 选择根证书 (.crt)格式. 参考- https://blog.csdn.net/weixin_43793525/article/details/136342927
  • centos或其他RHEL系统:
 cp your-root-ca.crt /etc/pki/ca-trust/source/anchors/
 update-ca-trust extract
  • ubuntu或debian系统:
sudo cp your-root-ca.crt /usr/local/share/ca-certificates/
sudo update-ca-certificates

# https签发原理

HTTPS证书签发的原理是确保客户端(如浏览器)能够验证服务器的真实身份,并建立加密通信的核心机制。以下是其核心步骤和原理:


# 1. 密钥对生成与证书请求(CSR)

  • 生成公私钥对:服务器管理员首先生成一对非对称加密的密钥(公钥和私钥)。私钥保密存储,公钥则需包含在证书中。
  • 创建证书签名请求(CSR):CSR包含以下信息:
    • 域名(Common Name):如 example.com
    • 组织信息:公司名称、地址等(可选,根据证书类型)。
    • 公钥:用于后续加密通信。
    • 签名:用服务器私钥对CSR内容签名,确保请求未被篡改。

# 2. CA验证申请者身份

证书颁发机构(CA)收到CSR后,需验证申请者对域名的控制权及组织真实性:

  • 域名验证
    • DNS验证:要求申请者在域名的DNS记录中添加特定TXT记录。
    • HTTP验证:在网站指定路径下放置CA提供的验证文件。
    • 邮箱验证:向域名注册时管理员邮箱(如 admin@example.com)发送确认邮件。
  • 组织验证(OV/EV证书)
    • 需提交营业执照等文件,CA人工审核(扩展验证证书EV需更严格核实)。

# 3. 证书签发与数字签名

  • 生成证书:验证通过后,CA将CSR中的信息(域名、公钥等)与附加信息(有效期、用途等)整合为证书。
  • 数字签名
    • CA使用自身私钥对证书的哈希值进行加密,生成签名。
    • 签名附加到证书中,形成完整的X.509标准证书。
  • 信任链建立
    • 证书中会包含签发它的CA信息。若由中间CA签发,还需包含中间证书,形成从根CA到终端证书的信任链。

# 4. 客户端验证证书

当用户访问网站时,服务器返回证书,客户端(如浏览器)按以下步骤验证:

  1. 证书完整性
    • 用CA的公钥解密签名,得到原始哈希值。
    • 重新计算证书哈希值,比对是否一致,确保未被篡改。
  2. 信任链校验
    • 检查证书是否由受信任的根CA签发(根证书预装在浏览器/操作系统中)。
    • 逐级验证中间CA证书,直到根CA。
  3. 有效性检查
    • 域名是否匹配(防止钓鱼网站)。
    • 证书是否在有效期内。
    • 是否被吊销(通过CRL或OCSP协议查询)。

# 5. 证书吊销机制

  • 证书吊销列表(CRL):CA定期发布被吊销证书的列表,客户端可下载校验。
  • 在线证书状态协议(OCSP):客户端实时查询证书状态。
  • OCSP Stapling:服务器主动获取OCSP响应并发送给客户端,提高效率。

# 核心作用

  • 身份认证:确保用户连接的是真实的服务器,而非中间人。
  • 加密通信:证书中的公钥用于交换对称加密密钥(如TLS握手),后续通信通过对称加密保护数据。

# 补充说明

  • 信任根CA的原因:操作系统和浏览器内置了受信任的根CA证书,形成信任锚点。
  • 自签名证书:无CA签发,浏览器会警告(因无法验证信任链),适用于测试环境。
  • 证书透明度(CT):CA需将颁发的证书公开到CT日志,防止恶意签发未授权的证书。

通过这一流程,HTTPS证书在加密的基础上,解决了“信任谁的公钥”这一根本问题,奠定了互联网安全通信的基础。