go

PCI认证服务端实现

TLS 1.2 和 TLS 1.3 是 **传输层安全协议(Transport Layer Security)** 的两个版本,用于在互联网通信中提供加密和身份验证功能。TLS 1.3 是 TLS 1.2 的升级版本,在安全性、性能和隐私方面都有显著改进。

访问-- -- --

PCI认证服务端实现

一、协议介绍 (公共前置内容)

TLS 1.2 和 TLS 1.3 是 传输层安全协议(Transport Layer Security) 的两个版本,用于在互联网通信中提供加密和身份验证功能。TLS 1.3 是 TLS 1.2 的升级版本,在安全性、性能和隐私方面都有显著改进。 下面是 TLS 1.2 和 TLS 1.3 的主要区别:

1、安全性增强

已知弱点存在一些可被利用的弱算法(如 RC4、CBC 模式下的 BEAST 攻击等)移除了所有不安全的旧算法
支持的加密套件多种算法组合,包括不安全的 MD5、SHA-1、RSA 密钥交换等只保留现代安全的算法,如 AES-GCM、ChaCha20-Poly1305 等
前向保密(PFS)可选,很多实现默认不启用强制要求使用,确保长期密钥泄露不影响历史通信安全

2、性能优化:握手过程简化

客户端到服务器ClientHello →ClientHello →
服务器响应← ServerHello, Certificate, ServerKeyExchange, ServerHelloDone← ServerHello, EncryptedExtensions, Certificate, Finished
密钥交换→ ClientKeyExchange, ChangeCipherSpec, Finished
RTT(往返次数)默认需要2 RTT(可以配置为 1 RTT)1 RTT就能完成握手,更快建立连接
0-RTT(零轮次握手)不支持支持(可提前发送数据,降低延迟)
说明
  • TLS 1.3 把密钥交换逻辑大幅简化,把很多步骤合并。
  • TLS 1.3 的 0-RTT 模式 允许客户端在第一个请求中就发送加密的应用数据,减少加载时间。

3、加密套件与算法改进

密钥交换算法RSA、DHE、ECDHE仅支持 ECDHE 和 DHE(强制前向保密)
身份验证机制使用 RSA 或 DH 进行身份验证身份验证与密钥交换分离,更灵活
加密+认证模式AEAD 和非-AEAD 都支持仅支持AEAD(Authenticated Encryption with Associated Data),如 AES-GCM、ChaCha20-Poly1305
哈希函数支持 SHA-1、MD5、SHA-256 等仅支持 SHA-256 及以上(推荐 SHA-256、SHA-384)

4、移除不安全特性

TLS 1.3 明确禁止了以下在 TLS 1.2 中可能存在的不安全做法:

  • RSA 密钥交换(易受攻击)
  • 压缩(容易导致 CRIME 攻击)
  • 自定义 Diffie-Hellman 参数(防止降级攻击)
  • 旧版 CBC 模式
  • 不安全的哈希算法(如 MD5、SHA-1)

5、总结对比表

发布时间2008 年2018 年
握手速度较慢(2 RTT)更快(1 RTT 或 0 RTT)
安全性依赖实现是否禁用不安全算法更高,默认启用现代安全算法
前向保密可选强制启用
加密套件多种复杂选择简化,仅保留安全选项
向后兼容支持 TLS 1.1、1.0 等不兼容 TLS 1.2 之前的协议
性能相对较低更高效,适合移动网络和 CDN 场景

二、服务端实现逻辑

实现逻辑有多种,java、python启http服务、nginx配置证书、go启服务等都能实现,本服务使用的是GO语言开发

一、实现

  • 实现双向认证服务端核心代码
    
    package main
    
    import (
    	"crypto/tls"
    	"crypto/x509"
    	"io/ioutil"
    	"log"
    	"net/http"
    )
    
    const path = "/uploadFiles"
    
    func startHTTPSServer() {
    	// 原来的 HTTPS 配置
    	rootCa := "./res/ca.crt"
    	serverCa := "./res/server.crt"
    	serverKey := "./res/server.key"
    	hostName := "xchengtech.com"
    	pool := newCertPool(rootCa)
    
    	s := &http.Server{
    		Addr:    ":5801",
    		Handler: http.FileServer(http.Dir(path)),
    		TLSConfig: &tls.Config{
    			ServerName: hostName,
    			ClientCAs:  pool,
    			ClientAuth: tls.RequireAndVerifyClientCert,
    		},
    	}
    
    	log.Printf("启动 HTTPS 文件服务在端口 :5801 ...")
    	err := s.ListenAndServeTLS(serverCa, serverKey)
    	if err != nil {
    		log.Printf("HTTPS server cannot run: %s", err.Error())
    	}
    }

上面代码中 startHTTPSServer 方法里面为主要实现方式, 使用的是 net/http 库,它是 go语言下标准库实现,设置了需要验证客户端证书,tls v1.2,**tls v1.3 ** 均可,主要看客户端采用哪种协议请求过来, &http.Server 配置了对双向认证的要求实现, s.ListenAndServeTLS(serverCa, serverKey) 启动端口监听客户端交换要求

二、验证

以如下文件获取为例 ,请求地址: https://192.168.110.4:5801/N0611/sp/002_signature_tampered_FW_N0611_V1.01.002.bin (是局域网地址) image-20250704173830108

1. 无证书验证不通

浏览器直接获取,后台开启了验证证书,验证不通过无法直接获取文件 image-20250704172842650

  • ssh命令验证
    • 从下图使用openssl方式验证连接服务端连接并双向同步,tls1.2版本和tls1.3没有给到客户端证书都没有连接成功 image-20250704174304213

2. 有证书能验证通过

  • ssh命令验证

    下图中指明客户端证书与ca文件,可以验证通过

    image-20250704180810756

访问 --

讨论与反馈