Unity 证书校验

一:证书校验的流程

在TLS/SSL握手阶段,完整的证书校验流程如下:

  1. 客户端发送ClientHello消息,包含支持的TLS版本、加密套件等信息
  2. 服务端响应ServerHello消息,并附带完整的证书链(通常包括叶子证书和中间证书)
  3. 客户端操作系统或应用内置的信任库会进行以下校验:
    • 证书链完整性验证:检查中间证书是否由可信根证书签发
    • 有效期检查:确认证书在有效期内
    • 域名匹配:验证证书中的CN或SAN字段是否包含请求的域名
    • CRL/OCSP检查(可选):查询证书吊销状态
  4. 若任一校验失败,客户端将终止连接并抛出安全警告

二:系统默认的证书校验

操作系统默认会执行多层校验:

  • 基础校验:
    • 证书格式合规性检查
    • 签名算法强度验证
    • 有效期检查(Not Before/Not After)
  • 中级校验:
    • 证书链验证(从叶子证书到根证书的完整链路)
    • 主机名验证(支持精确匹配和通配符匹配)
  • 高级校验(可选配置):
    • 证书透明度(CT)日志验证
    • 证书策略(CP/CPS)检查

三:服务端返回的证书信息

现代Web服务器返回的证书包通常包含:

  • 主证书(叶子证书):
    • 包含服务器公钥
    • 明确绑定的域名(CN/SAN)
    • 由中间CA签发
  • 中间证书(Intermediate CA):
    • 用于构建证书链
    • 由根CA签发
  • 扩展信息(可选):
    • OCSP响应
    • SCT(证书透明度)证明

根证书通常不包含在服务器响应中,因为主流操作系统和浏览器都内置了常见根证书库。

四:证书层级关系详解

典型的三层证书体系:

  1. 根证书(Root CA):
    • 自签名证书
    • 预装在操作系统/浏览器中
    • 示例:DigiCert Global Root CA
  2. 中间证书(Intermediate CA):
    • 由根证书签发
    • 可以签发多个叶子证书
    • 示例:DigiCert SHA2 Secure Server CA
  3. 叶子证书(End-entity):
    • 绑定具体域名
    • 包含服务器公钥
    • 示例:api.example.com的SSL证书

这种层级设计既保证了安全性(根证书离线存储),又提供了灵活性(中间证书可轮换)。

五:证书类型识别方法

可通过以下字段区分证书类型:

  • 根证书:

    复制代码
    Issuer: CN=DigiCert Global Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US
    Subject: CN=DigiCert Global Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US

    (Issuer和Subject相同)

  • 中间证书:

    复制代码
    Issuer: CN=DigiCert Global Root CA
    Subject: CN=DigiCert SHA2 Secure Server CA

    (Issuer指向根证书,Subject为中间CA名称)

六:证书校验技术详解

DER(Distinguished Encoding Rules):

  • ASN.1的二进制编码格式
  • 浏览器实际传输的证书格式
  • 查看方法:openssl x509 -in cert.crt -inform der -text

指纹校验(Certificate Fingerprint):

复制代码
// 计算示例:
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] digest = md.digest(cert.getEncoded());
String fingerprint = bytesToHex(digest); // 转换为HEX字符串

特点:

  • 证书任何改动都会改变指纹
  • 适用于严格固定证书场景

SPKI(Subject Public Key Info)Pin:

复制代码
# 计算示例:
from hashlib import sha256
import base64

pubkey = cert.public_key().public_bytes(
    encoding=serialization.Encoding.DER,
    format=serialization.PublicFormat.SubjectPublicKeyInfo
)
pin = base64.b64encode(sha256(pubkey).digest())

优势:

  • 允许证书轮换(只要公钥不变)
  • 兼容证书自动续期

七:证书校验最佳实践

生产环境推荐组合方案:

  1. 基础层:系统默认校验(证书链+域名)
  2. 增强层:SPKI Pin(防止中间人攻击)
  3. 监控层:证书透明度校验(预防错误签发)
  1. Unity证书校验实现

增强型校验示例:

复制代码
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;

class CustomCertificateHandler : CertificateHandler
{
    // 可信指纹库(可配置多个备份证书)
    private static readonly HashSet<string> TRUSTED_FINGERPRINTS = new()
    {
        "E3:5D:28:41:...", // 主证书
        "A1:B2:C3:D4:..."  // 备用证书
    };

    protected override bool ValidateCertificate(byte[] certificateData)
    {
        #if UNITY_EDITOR || DEVELOPMENT_BUILD
            return true; // 开发环境跳过校验
        #endif

        try {
            using var cert = new X509Certificate2(certificateData);
            
            // 基础校验
            if (DateTime.Now < cert.NotBefore || DateTime.Now > cert.NotAfter)
                return false;

            // 增强校验
            var fingerprint = cert.GetCertHashString(HashAlgorithmName.SHA256);
            return TRUSTED_FINGERPRINTS.Contains(fingerprint);
        }
        catch {
            return false;
        }
    }
}

实现建议:

  • 使用哈希集合支持多证书
  • 添加有效期二次验证
  • 区分开发/生产环境
  • 错误处理机制
相关推荐
xcLeigh2 小时前
Unity基础:C#脚本的创建与挂载——让你的游戏物体活起来
游戏·unity·c#·教程
DaLiangChen1 天前
Vuforia 地面识别案例
unity·ar
江畔柳前堤1 天前
YOLO 目标检测全流程深度剖析
人工智能·yolo·目标检测·计算机视觉·unity·面试·vllm
魔术师Dix1 天前
一个轮子:Luban Skill 制作演示
游戏·unity·ai编程
xcLeigh2 天前
Unity基础:Light灯光组件入门——Directional Light、Point Light与Spotlight
unity·游戏引擎·教程
郝学胜-神的一滴2 天前
[简化版 GAMES 104] 现代游戏引擎 04:从0到1构建你的游戏世界
c++·游戏·unity·游戏引擎·软件工程·unreal engine
是嘟嘟啊3 天前
【Unity DOTS】EntityCommandBuffer 与 JobHandle
unity·ecs·dots·unity dots·job·burst·burstjob
xcLeigh3 天前
Unity基础:Camera相机组件详解——透视投影与正交投影的区别
数码相机·unity·游戏引擎
玖玥拾3 天前
Unity3D RPG 入门项目(二)移动 Bug 修复、环绕相机、NPC 任务系统、UI 穿透处理
unity·游戏引擎