68 lines
2.4 KiB
Swift
68 lines
2.4 KiB
Swift
//
|
|
// SDLSuperTLSVerifier.swift
|
|
// punchnet
|
|
//
|
|
// Created by 安礼成 on 2026/5/22.
|
|
//
|
|
import Foundation
|
|
import CryptoKit
|
|
import Security
|
|
|
|
enum SDLSuperTLSVerifier {
|
|
// 你的 Base64 公钥指纹
|
|
static let pinnedPublicKeyHashes = [
|
|
// 正式服务器的
|
|
"Q41r6hbMWEVyxo6heNAH4Wx/TH5NNOWlNif9bewcJ3E=".lowercased(),
|
|
|
|
// 测试服务器
|
|
"oeU0bWqLWMdn79s4ZHz6IRwXmFX4p70u/Qt9VrsDIb4=".lowercased()
|
|
]
|
|
|
|
static func verify(trust: sec_trust_t, host: String) -> Bool {
|
|
let secTrust = sec_trust_copy_ref(trust).takeRetainedValue()
|
|
|
|
// --- Step 1: 系统验证 ---
|
|
var error: CFError?
|
|
guard SecTrustEvaluateWithError(secTrust, &error) else {
|
|
SDLLogger.log("❌ 系统证书验证失败: \(error?.localizedDescription ?? "未知错误")", for: .debug)
|
|
return false
|
|
}
|
|
|
|
// --- Step 2: 主机名验证 ---
|
|
let policy = SecPolicyCreateSSL(true, host as CFString)
|
|
SecTrustSetPolicies(secTrust, policy)
|
|
|
|
guard SecTrustEvaluateWithError(secTrust, &error) else {
|
|
SDLLogger.log("❌ 主机名校验失败: \(error?.localizedDescription ?? "未知错误")", for: .debug)
|
|
return false
|
|
}
|
|
|
|
// --- Step 3: 获取叶子证书 ---
|
|
guard let chain = SecTrustCopyCertificateChain(secTrust) as? [SecCertificate],
|
|
let leafCertificate = chain.first else {
|
|
SDLLogger.log("❌ 无法获取证书链或叶子证书", for: .debug)
|
|
return false
|
|
}
|
|
|
|
// --- Step 4: 提取公钥 ---
|
|
guard let publicKey = SecCertificateCopyKey(leafCertificate),
|
|
let publicKeyData = SecKeyCopyExternalRepresentation(publicKey, nil) as Data? else {
|
|
SDLLogger.log("❌ 无法提取公钥", for: .debug)
|
|
return false
|
|
}
|
|
|
|
// --- Step 5: SHA256 校验 ---
|
|
let hash = SHA256.hash(data: publicKeyData)
|
|
let hashBase64 = Data(hash).base64EncodedString().lowercased()
|
|
|
|
if pinnedPublicKeyHashes.contains(hashBase64) {
|
|
SDLLogger.log("✅ 公钥校验通过", for: .debug)
|
|
return true
|
|
} else {
|
|
SDLLogger.log("⚠️ 公钥不匹配! 收到: \(hashBase64), config hashes: \(pinnedPublicKeyHashes)", for: .debug)
|
|
return false
|
|
}
|
|
}
|
|
|
|
}
|