下面整套:生成证书 → Nginx(最常用)配置 → 后端业务服务(Go / Python 等)两种模式(Nginx 做 TLS 终止、服务本身直接监听 HTTPS),以及配套校验、轮换、抓包调试要点,全部配合上面 iOS 的 SSL Pinning。
重要区分
- 如果 iOS 是固定「根 CA」:服务器后续可以用同一个根重签叶子证书,不用发新版 App;
- 如果 iOS 固定「叶子证书 / 叶子公钥」:证书一变,App 必须更新(适合内网、可控环境)。
一、一键生成自签证书(推荐带 SAN)
苹果现在拒绝不带 SAN 的证书,只写 CN 会校验失败。新建 openssl.cnf:
[req]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
x509_extensions = v3_ca
prompt = no
[req_distinguished_name]
C = CN
ST = Beijing
L = Beijing
O = AxPlayer
OU = Dev
CN = api.kidsmiless.cn
[req_ext]
subjectAltName = @alt_names
[v3_ca]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = api.kixxmiless.cn
IP.1 = 8.152.98.xx
生成(自签叶子证书;如果你想要根 CA 体系,先生成根 CA,再签发服务证书)
# 私钥
openssl genrsa -out server.key 2048
# 证书请求 + 自签,有效期 3650 天
openssl req -new -x509 -days 3650 -key server.key \
-out server.crt \
-config openssl.cnf \
-extensions v3_ca
导出给 iOS 使用的 DER(前面 iOS 代码要用)
openssl x509 -in server.crt -outform DER -out server.der
-
server.crt:PEM,给 Nginx / Caddy / Apache -
server.key:私钥,务必权限chmod 600,不要外泄 -
server.der:丢进 Xcode

abc
服务端go语言集成
main.go 代码
// 改前
// if err := r.Run(cfg.ServerAddr); err != nil {
// 改后
if err := r.RunTLS(cfg.ServerAddr, cfg.TLSCert, cfg.TLSKey); err != nil {
log.Fatalf("run server: %v", err)
}
config.go代码
type Config struct {
MySQLDSN string
ServerAddr string
AdminToken string
GinMode string
TLSCert string // ← 新增
TLSKey string // ← 新增
}
func Load() *Config {
return &Config{
MySQLDSN: getEnv("MYSQL_DSN", "..."),
ServerAddr: getEnv("SERVER_ADDR", ":8443"), // 改默认端口为 8443
AdminToken: getEnv("ADMIN_TOKEN", "dev-token-change-me"),
GinMode: getEnv("GIN_MODE", "debug"),
TLSCert: getEnv("TLS_CERT", "/root/music_server/sslmake/server.crt"), // ← 新增
TLSKey: getEnv("TLS_KEY", "/root/music_server/sslmake/server.key"), // ← 新增
}
}