如何在macOS开发中给 PKG 签名和公证(productsign+notarytool)

ops/2024/11/1 18:09:38/

在这里插入图片描述
在macOS中,给PKG文件进行签名是一个确保用户能够顺利无警告地安装软件的重要步骤。以下是给PKG签名的详细步骤:

一、准备阶段

  1. 获取开发者账号和证书

    • 首先,需要在苹果开发者网站(Apple Developer)注册一个有效的开发者账号。
    • 登录开发者账号后,进入“Certificates, IDs & Profiles”页面。
    • 创建并下载“Developer ID Application”证书和“Developer ID Installer”证书。这两个证书分别用于签名应用程序和PKG安装包。
    • 将下载的证书双击安装到“钥匙串访问”中。
  2. 打包PKG文件

    • 使用Packages工具或其他打包工具,将需要分发的应用程序和相关文件打包成一个PKG安装包。
    • 在打包过程中,可以添加安装前和安装后的脚本来执行一些自定义操作。

二、签名阶段

  1. 获取证书名称

    • 打开终端,输入命令security find-identity -v,列出所有已安装的证书。
    • 找到与“Developer ID Installer”相关的证书名称,通常格式为“Developer ID Installer: 开发者名称 (证书标识符)”。
  2. 签名PKG文件

    • 使用productsign命令对PKG文件进行签名。命令格式如下:
      productsign --sign "Developer ID Installer: 开发者名称 (证书标识符)" 原始PKG文件路径 签名后的PKG文件路径
      
    • 例如:
      productsign --sign "Developer ID Installer: Your Company, Co., LTD (2988ZTAM4B)" App.pkg App-Signed.pkg
      
    • 这将生成一个新的签名后的PKG文件。

三、验证签名

  1. 验证PKG文件签名
    • 使用pkgutil命令验证PKG文件的签名是否有效。命令格式如下:
      pkgutil --check-signature 签名后的PKG文件路径
      
    • 如果签名有效,命令将输出“signed by a developer certificate issued by Apple for distribution”。

四、公证阶段(可选)

从macOS 10.14.5开始,苹果要求所有分发的软件都必须经过公证(Notarization)。公证过程如下:

  1. 准备已签名的软件包
    在公证之前,你需要确保你的 .pkg 文件已经使用 codesign 命令进行了签名。

  2. 将公证凭证存储到 macOS 的钥匙串中

    xcrun notarytool store-credentials "$KEYCHAIN_PROFILE" \--apple-id "$APPLE_ID" \--team-id "$TEAM_ID" \--password "$APP_SPECIFIC_PASSWORD"
    
  3. 上传PKG文件到苹果服务器
    使用 notarytool 提交你的软件包进行公证。这一步会将你的软件包上传到 Apple 的公证服务,并启动公证流程。

    xcrun notarytool submit /path/to/your/signed/package.pkg --keychain-profile $KEYCHAIN_PROFILE --wait
    
    • /path/to/your/signed/package.pkg 是你的已签名软件包的路径。
    • --keychain-profile 参数用于指定包含你签名证书的钥匙串配置文件(可选,如果证书在默认钥匙串中则不需要)。
    • --wait 参数告诉 notarytool 等待公证完成并返回结果。

    如果公证成功,notarytool 会返回一个 RequestUUID,你可以使用这个 UUID 来查询公证状态或进行后续操作。

  4. 检查公证结果(如果未使用 --wait):
    如果你没有使用 --wait 参数,你需要使用返回的 RequestUUID 来检查公证状态。

    xcrun notarytool status <RequestUUID>
    

    替换 <RequestUUID> 为你实际获得的 UUID。

五、盖章步骤

一旦你的软件包通过了公证,你就可以使用 stapler 工具对其进行盖章。

  1. 对软件包进行盖章
    使用 stapler 工具对你的软件包进行盖章,以表明它已经通过了 Apple 的公证服务。

    xcrun stapler staple /path/to/your/signed/package.pkg
    
    • /path/to/your/signed/package.pkg 是你的已签名且已公证的软件包的路径。
  2. 验证盖章结果(可选):
    你可以使用 stapler 工具来验证你的软件包是否已经被正确盖章。

    xcrun stapler validate /path/to/your/stapled/package.pkg
    
    • /path/to/your/stapled/package.pkg 是你的已盖章软件包的路径。

如果所有步骤都成功完成,你的软件包现在应该已经准备好分发给用户了。用户可以通过 macOS 的“安装未知开发者应用”的安全设置来安装你的软件包,而不会因为未经验证的应用程序而被阻止。

六、命令集合

以下是一个简要的流程,以及一个相应的 .sh 脚本示例:
1.用于签名.pkg 文件(productsign.sh)。

#!/bin/bash# 证书名称,使用"security find-identity -v"命令查找并替换
CERT_NAME="Developer ID Installer: Your Company Co., Ltd. (4H8C8HR626)"# 原始PKG文件路径,替换为你的PKG文件路径
PKG_PATH="Install App.pkg"# 签名后的PKG文件路径,替换为你想要保存的签名PKG文件路径
SIGNED_PKG_PATH="../Install App.pkg"# 签名PKG文件
echo "正在签名PKG文件..."
productsign --sign "$CERT_NAME" "$PKG_PATH" "$SIGNED_PKG_PATH"
if [ $? -ne 0 ]; thenecho "签名PKG文件失败"exit 1
fi
echo "PKG文件签名成功"# 验证签名
echo "正在验证PKG文件签名..."
pkgutil --check-signature "$SIGNED_PKG_PATH"
if [ $? -ne 0 ]; thenecho "验证PKG文件签名失败"exit 1
fi
echo "PKG文件签名验证成功"
echo "所有脚本执行成功!"

2.用于签名和公证 .pkg 文件(productsign-online-notarytool.sh)。

#!/bin/bash# 证书名称,使用"security find-identity -v"命令查找并替换
CERT_NAME="Developer ID Installer: Your Company Co., Ltd. (4H8C8HR626)"
# 开发者团队ID
# 从CERT_NAME中提取TEAM_ID
# 假设TEAM_ID总是位于最后一对括号内
# TEAM_ID="4H8C8HR626"
TEAM_ID=$(echo "$CERT_NAME" | awk -F'[()]' '{print $2}')# 原始PKG文件路径,替换为你的PKG文件路径
PKG_PATH="Install App.pkg"# 签名后的PKG文件路径,替换为你想要保存的签名PKG文件路径
SIGNED_PKG_PATH="../Install App.pkg"# 应用的Bundle ID,替换为你的应用的Bundle ID
APP_BUNDLE_ID="com.company.pkg.InsallApp"# 苹果开发者账号
APPLE_ID="apple@163.com"# 应用专属密码(不是账号的登录密码),替换为你的应用专属密码
APP_SPECIFIC_PASSWORD="wet-erwc-ssdf-hqaf"KEYCHAIN_PROFILE="my_notary_credentials"            # 钥匙串配置文件名称# 签名PKG文件
echo "正在签名PKG文件..."
productsign --sign "$CERT_NAME" "$PKG_PATH" "$SIGNED_PKG_PATH"
if [ $? -ne 0 ]; thenecho "签名PKG文件失败"exit 1
fi
echo "PKG文件签名成功"# 验证签名
echo "正在验证PKG文件签名..."
pkgutil --check-signature "$SIGNED_PKG_PATH"
if [ $? -ne 0 ]; thenecho "验证PKG文件签名失败"exit 1
fi
echo "PKG文件签名验证成功"# ==== Xcode 16 ===
# 存储公证凭证到钥匙串
echo "正在存储公证凭证..."
xcrun notarytool store-credentials "$KEYCHAIN_PROFILE" \--apple-id "$APPLE_ID" \--team-id "$TEAM_ID" \--password "$APP_SPECIFIC_PASSWORD"
if [ $? -ne 0 ]; thenecho "存储凭证失败!"exit 1
fi# 上传PKG文件进行公证并获取RequestUUID
echo "正在上传PKG文件进行公证, 请稍等..."
OUTPUT=$(xcrun notarytool submit "$SIGNED_PKG_PATH" \--keychain-profile "$KEYCHAIN_PROFILE" \--wait 2>&1)echo "上传输出信息:"
echo "$OUTPUT"# 检查是否成功获取到RequestUUID
REQUEST_UUID=$(echo "$OUTPUT" | awk -F': ' '/id: / {print $2; exit}')
if [ -z "$REQUEST_UUID" ]; thenecho "上传PKG文件进行公证失败,未获取到RequestUUID"echo "错误信息: $OUTPUT"exit 1
fi
echo "PKG文件已上传进行公证,RequestUUID: $REQUEST_UUID"# 查询公证进度
echo "正在等待公证完成..."
WAIT_TIME=0
INTERVAL=30
MAX_WAIT_TIME=100 # 10分钟=600秒
while [ $WAIT_TIME -lt $MAX_WAIT_TIME ]; doxcrun notarytool info "$REQUEST_UUID" --keychain-profile "$KEYCHAIN_PROFILE" > ./notary_info.logSTATUS=$(grep -i "status:" ./notary_info.log | awk -F': ' '{print $2}')ERROR=$(grep -i "error:" ./notary_info.log | awk -F': ' '{print $2}')if [ "$STATUS" == "Accepted" ]; thenecho "公证完成!"breakelif [ "$STATUS" == "Success" ]; thenecho "公证成功!"breakelif [ "$STATUS" == "invalid" ]; thenecho "公证失败,状态为无效!"exit 1elseecho "公证进行中($WAIT_TIME)..."echo "等待$INTERVAL 秒后再次检查..."sleep $INTERVALWAIT_TIME=$((WAIT_TIME + INTERVAL))fiif [ $WAIT_TIME -ge $MAX_WAIT_TIME ]; thenecho "公证超时!"exit 1fi
done# 盖章
echo "正在对签名的安装包进行盖章..."
xcrun stapler staple "$SIGNED_PKG_PATH"
if [ $? -ne 0 ]; thenecho "盖章失败!"
elseecho "盖章成功!"exit 1
fi# 验证
echo "正在验证已经盖章的签名的安装包..."
xcrun stapler staple -v "$SIGNED_PKG_PATH"
if [ $? -ne 0 ]; thenecho "验证失败!"exit 1
elseecho "盖章和验证成功!"
fiecho "PKG文件签名和公证流程全部完成"
echo "所有脚本执行成功!"

请注意,这些步骤假设你已经具备了必要的 Apple Developer 账户、证书和配置文件,并且你的 macOS 系统已经安装了 Xcode 和 Xcode Command Line Tools。如果你遇到任何问题,请检查你的证书、配置文件和路径是否正确,以及你是否拥有执行这些命令的适当权限。

cd build
chmod +x productsign.sh
chmod +x productsign-online-notarytool.sh
./productsign.sh  #或者仅签名
./productsign-online-notarytool.sh # 或者签名加公正[用于需要自动更新]

在这里插入图片描述

参考:

https://taoofcoding.tech/blogs/2022-11-13/use-notarytool-to-notary-macos-app
https://blog.csdn.net/Crystal_Mr_Rose/article/details/136351429

macOS 工具 - 查看PKG文件内容, App下载安装
SuspiciousPackage官方下载地址(免费):
http://www.mothersruin.com/software/SuspiciousPackage/get.html

Mac OS平台下应用程序PKG安装包制作工具Packages, App下载安装
Packages官方下载地址(免费):
http://s.sudre.free.fr/Software/Packages/resources.html


http://www.ppmy.cn/ops/130195.html

相关文章

模拟算法 (算法详解+例题)

目录 一、什么是模拟二、模拟算法的特点和技巧三、模拟OJ题3.1、替换所有的问号3.2、提莫攻击3.3、N字形变换3.4、外观数列3.5、数青蛙 一、什么是模拟 模拟是对真实事物或者过程的虚拟。在编程时为了实现某个功能&#xff0c;可以用语言来模拟那个功能&#xff0c;模拟成功也…

程序中怎样用最简单方法实现写excel文档

很多开发语言都能找到excel文档读写的库&#xff0c;但是在资源极其受限的环境下开发&#xff0c;引入这些库会带来兼容性问题。因为一个小功能引入一堆库&#xff0c;我始终觉得划不来。看到有项目引用的jar包有一百多个&#xff0c;看着头麻&#xff0c;根本搞不清谁依赖谁。…

Canvas字体高度计算与PDF高度如何统一

因为英文书写时并不是像汉字一样就是一个方块字&#xff0c;比如下图p有部分是在基线以下&#xff0c;其他的字体都是以基线为参照书写&#xff0c;所以在Canvas中字(或字母)所占的高度是&#xff1a; metrics.boundingBoxAscent metrics.boundingBoxDescent上行间距下行间距…

vue 禁用element-ui calendar 取消非本月日期的点击事件

需求描述&#xff1a;原本的日历组件不是本月的日期是灰色的&#xff0c;且点击后会跳转到对应的月份&#xff0c;现在不想它跳转&#xff0c;需要禁用它的点击事件 方法&#xff1a;使用css的pointer-events:none属性即可&#xff0c;把不是当前月份的日历表格的td属性修改 :…

【STM32】SD卡

(一)常用卡的认识 在学习这个内容之前&#xff0c;作为生活小白的我对于SD卡、TF卡、SIM卡毫无了解&#xff0c;晕头转向。 SD卡&#xff1a;Secure Digital Card的英文缩写&#xff0c;直译就是“安全数字卡”。一般用于大一些的电子设备比如&#xff1a;电脑、数码相机、AV…

python debug作业

任务类型任务内容预计耗时闯关任务Leetcode 383(笔记中提交代码与leetcode提交通过截图)20mins闯关任务Vscode连接InternStudio debug笔记10mins可选任务pip安装到指定目录10mins leetcode题目解析&#xff1a; 解题思路 字符统计&#xff1a;使用 Python 的 Counter 类统计 ra…

三代CAN技术演进:从CAN CC到CAN XL的创新路径(下篇)

欢迎关注虹科&#xff0c;为您提供最新资讯&#xff01; #CAN #工业通信 #CAN XL 导读 CAN&#xff08;Controller Area Network&#xff09;是一种用于实时应用的串行通信协议&#xff0c;广泛应用于汽车和工业电子设备中&#xff0c;以实现不同设备间的高效数据交换。它采…

程序员如何平衡日常编码工作与提升式学习

程序员如何平衡日常编码工作与提升式学习 在快速变化的技术世界中&#xff0c;作为程序员的你可能常常感到疲惫不堪&#xff0c;尤其是在日常的编码工作与个人成长之间寻找平衡时。如何在应对紧迫的项目截止日期同时&#xff0c;又能不断提升自己的技能&#xff1f;本文将探讨…