首页
/ fastlane pem 完全指南:自动生成与续期 iOS 推送证书(.pem/.cer/.p12)

fastlane pem 完全指南:自动生成与续期 iOS 推送证书(.pem/.cer/.p12)

2026-09-05 11:09:25作者:范靓好Udolf

iOS 推送通知依赖 Apple 签名的推送证书,手工在 Developer Portal 创建证书、导出 .pem 文件的过程繁琐且容易过期遗忘。fastlane 内置的 pem 工具(对应 action 为 get_push_certificate)可以一条命令完成签名请求生成、证书申请、证书下载以及 .pem 文件产出的全流程,并在现有证书仍在有效期内时自动跳过重复创建。读完本文,你将掌握 pem 的完整用法、全部参数与环境变量、空密码 p12 文件的校验技巧,以及其底层如何通过 Spaceship 与 Apple Developer Portal 交互的实现原理。

fastlane pem 工具标识

功能概览

pem 的核心功能只有一件:为你的推送服务器生成 .pem 文件。运行 fastlane pem 时,它会依次完成:

  • 创建新的证书签名请求(CSR);
  • 在 Apple Developer Portal 上创建新的推送证书;
  • 下载该证书;
  • 在当前工作目录生成新的 .pem 文件,供你上传到推送服务器。

需要注意两点边界:

  1. pem 不负责把文件上传到你的服务器——它只生成本地文件,上传逻辑需要自己实现(get_push_certificate action 提供了 new_profile 回调,见下文);
  2. pem 永远不会吊销你现有的证书,也无法下载已存在的推送证书,因为私钥只存在于当初创建它的那台机器上。如果现有证书仍活跃,pem 只会提示并直接返回。

关于命名:.pem 文件中实际上拼接了 证书(.cer 内容)+ 私钥;此外 pem 还可以按配置额外输出 .p12.pkey 文件。

基本用法

最简单的调用只有这一条命令:

fastlane pem

如果你的 Apple ID 或 App Identifier 已在 Appfile 中配置,甚至无需任何参数。也可以显式传参:

fastlane pem -a com.krausefx.app -u your@apple-id.com

按证书类型区分的常用命令:

# 默认:生产(Production)推送证书
fastlane pem

# 开发环境(Development)推送证书
fastlane pem --development

# Website Push 证书(Web Push 服务使用)
fastlane pem --website_push

# VoIP Services 证书(PushKit 所需类型)
fastlane pem --voip_push

强制创建新证书:当现有推送证书有效期还剩 30 天以上时,pem 不会创建新证书;如需强制新建,加 --force

fastlane pem --force

其他常用操作:

# 为 p12 文件设置密码
fastlane pem -p "MyPass"

# 指定输出 .pem 文件名
fastlane pem -o my.pem

# 查看所有可用选项
fastlane action pem

完整参数与选项

pem 的选项定义在 pem/lib/pem/options.rb 中,fastlane action pem 展示的选项即来源于此。结合源码,完整参数如下(均支持对应环境变量):

参数 短选项 环境变量 默认值 说明
platform -m PEM_PLATFORM ios 证书平台,仅支持 iosmacos(源码中有 verify_block 校验,传其他值会直接报错)
development PEM_DEVELOPMENT false 续期开发推送证书而非生产证书
website_push PEM_WEBSITE_PUSH false 创建 Website Push 证书(与 development 互斥)
voip_push PEM_VOIP_PUSH false 创建 VoIP Services 证书(与 developmentwebsite_push 互斥)
generate_p12 PEM_GENERATE_P12_FILE true 是否额外生成 .p12 文件(默认开启,可关闭)
active_days_limit PEM_ACTIVE_DAYS_LIMIT 30 现有证书有效期短于此天数时才重新生成;必须为正整数
force PEM_FORCE false 即使现有证书仍活跃超过阈值也强制创建新证书
save_private_key -s PEM_SAVE_PRIVATEKEY true 是否保存 RSA 私钥(.pkey 文件)
app_identifier -a PEM_APP_IDENTIFIER 取自 Appfileapp_identifier 应用的 Bundle ID
username -u PEM_USERNAME 取自 Appfileapple_dev_portal_id / apple_id Apple ID 用户名
team_id -b PEM_TEAM_ID 取自 Appfileteam_id 属于多个团队时的团队 ID(可选)
team_name -l PEM_TEAM_NAME 取自 Appfileteam_name 属于多个团队时的团队名称(可选)
p12_password -p PEM_P12_PASSWORD p12 文件的密码(标记为敏感参数,摘要输出时会被隐藏)
pem_name -o PEM_FILE_NAME 指定生成的 .pem 文件名(可选)
output_path -e PEM_OUTPUT_PATH . 存放证书、私钥与 p12 的目录(可选)

从源码结构看,几个默认值的行为细节值得注意:

  • 默认生成三个文件。在 pem/lib/pem/manager.rbcreate_certificate 中:先按 save_private_key(默认 true)写出 .pkey 私钥;再按 generate_p12(默认 true)用 OpenSSL::PKCS12 写出 .p12;最后写出 .pem,其内容是 X.509 证书的 PEM + 私钥 PEM 的拼接x509_certificate.to_pem + pkey.to_pem)。
  • 文件名规则:不指定 pem_name 时,文件名为 {certificate_type}_{app_identifier}_{platform},例如 production_com.example.app_ios.pem;证书类型前缀由 certificate_type 方法决定,取值为 productiondevelopmentwebsitevoip。这个命名规则在测试用例 pem/spec/manager_spec.rb 中被明确断言,例如 production_com.krausefx.app_ios.pemvoip_com.krausefx.app_ios.pemproduction_com.krausefx.app_macos.pem
  • Appfile 回退app_identifierusernameteam_idteam_name 的默认值均通过 CredentialsManager::AppfileConfig.try_fetch_value 动态取自项目中的 Appfile,因此把 Apple 账号信息写进 Appfile 后,CI 上运行 pem 就无需再传 -u-a
  • team 选项的环境变量联动team_idteam_nameverify_block 会同步写入 ENV["FASTLANE_TEAM_ID"] / ENV["FASTLANE_TEAM_NAME"],供 Spaceship 登录选团队时使用。

在 Fastfile 中使用 get_push_certificate

pem 命令对应的 action 是 fastlane/lib/fastlane/actions/get_push_certificate.rb 中的 GetPushCertificateAction,而 fastlane/lib/fastlane/actions/pem.rb 中的 PemAction 只是它的别名(描述明确写着 "Alias for the get_push_certificate action")。该 action 在 CLI 选项之外还支持一个 new_profile 回调,仅当确实生成了新证书时才会被调用,非常适合用来自动把新 .pem 上传到推送服务器:

get_push_certificate(
  force: true, # 即使旧证书仍有效也创建新的
  app_identifier: "net.sunapps.9", # 可选的 App Bundle ID
  save_private_key: true,
  new_profile: proc do |profile_path|
    puts profile_path # 新生成 PEM 文件的绝对路径
    # 在此插入上传 PEM 文件到服务器的代码
  end
)

action 层还会把 PEM::Manager.start 的返回值(新证书路径)透传给回调;在 Helper.test?(单元测试模式)下则直接使用 ./test.pem 占位路径,避免测试时真实访问 Apple 服务端——这一分支同样可以在源码中看到。

空密码 p12 与 Keychain Access 的注意事项

pem 允许不指定密码(或空字符串密码)生成合法的 p12 文件:源码中 p12_password == "" ? nil 的写法(见 pem/lib/pem/manager.rb 第 82 行附近)表明空密码会被转换为 nil 传给 OpenSSL,生成无密码 p12。

但要注意:macOS 的 Keychain Access 无法直接打开这种无密码 p12(即使文件本身是合法的)。可以用 OpenSSL 校验:

openssl pkcs12 -info -in my.p12

如果你必须把 p12 导入钥匙串(例如用 Knuff 或 Pusher 之类的应用测试推送),可以用 OpenSSL 把 p12 转成 pem 再转回带密码的 p12:

% openssl pkcs12 -in my.p12 -out my.pem
Enter Import Password:
  <直接回车:该 p12 没有密码>
MAC verified OK
Enter your pem passphrase:
  <输入一个临时密码用于加密 pem 文件>

% openssl pkcs12 -export -in my.pem -out my-with-passphrase.p12
Enter pass phrase for temp.pem:
  <输入刚才的临时密码解密 pem 文件>

Enter Export Password:
  <输入用于加密新 p12 文件的密码>

工作流程与底层实现

pem 通过 spaceship 与 Apple Developer Portal 通信。核心流程在 pem/lib/pem/manager.rb 中,可拆为三步:

  1. 登录login 方法调用 Spaceship.login(PEM.config[:username], nil) 后用 Spaceship.client.select_team 选定团队。用户名可来自命令行、PEM_USERNAME 或 Appfile,密码由 fastlane 的 credentials_manager(CredentialsManager)统一管理——这也是文档中 "How is my password stored?" 一节的实现依据:密码不会明文写在 Fastfile 里,而是通过 fastlane 的凭据管理器读取。
  2. 检查现有证书start 方法会拉取 certificate.all 并按到期时间倒序排序(certificate_sorted),匹配 owner_name == app_identifier 的现有证书,计算剩余天数。剩余天数超过 active_days_limit(默认 30)且未设置 force 时,直接提示 "No need to create a new one" 并返回,不做任何创建动作
  3. 创建并落盘create_certificate 先调用 Spaceship.certificate.create_certificate_signing_request 在本机生成 CSR 与 RSA 私钥,再用 certificate.create!(csr: csr, bundle_id: ...) 提交到 Portal。如果 Apple 返回 "You already have a current..."(同一 App/环境已存在 2 个活跃推送证书),会给出明确的 user_error! 提示:需要先吊销旧证书才能创建新证书。成功后 cert.download 取回 X.509 证书,再按上文所述落盘 .pkey.p12.pem

证书类型的路由逻辑同样在这份源码里(certificate 方法):website_pushSpaceship.certificate.website_pushvoip_pushvoip_push;否则按 platformios / macos)与 development 开关映射到 production_pushdevelopment_pushmac_production_pushmac_development_push 四种之一,其他平台值会报 "Unsupported platform" 错误。

相关的证书生命周期管理

pem 只处理推送证书。若要同时自动化 App Store 开发证书 的创建与续期,可配合 cert 工具(cert/lib/cert/runner.rb);若要自动化 Provisioning Profile 的创建与分发,可使用 matchmatch/lib/match/runner.rb)。三者组合后,推送、签名、描述文件即可全部纳入 CI。

小结

  • fastlane pem 一条命令完成推送证书 CSR 生成、申请、下载与 .pem 落盘,并默认额外输出 .p12.pkey
  • 现有证书有效期超过 30 天(active_days_limit 可调)时自动跳过创建,--force 可强制新建;pem 永不吊销现有证书;
  • 支持生产/开发/Website Push/VoIP 四种证书类型,以及 ios/macos 双平台;
  • 在 Fastfile 中应优先使用 get_push_certificate action 及其 new_profile 回调,把新证书自动上传到你的推送服务器;
  • Apple 账号凭据建议放入 Appfile 并交由 fastlane 的 credentials_manager 管理,参数细节以 fastlane action pem 输出为准。
登录后查看全文
热门项目推荐
相关项目推荐