iOS构建时通过Shell脚本一次性生成私钥并存入钥匙串的疑问
iOS构建阶段生成私钥并存入钥匙串(仅执行一次)
问题根源
你当前的脚本报错,是因为openssl genpkey加了-aes256参数后,会要求交互式输入加密密码,但Xcode构建脚本是无交互环境,命令无法获取输入导致执行失败返回非零码。另外你的脚本还没实现存入钥匙串和仅执行一次的核心需求。
完整解决脚本
下面是满足所有要求的脚本,包含私钥生成、钥匙串存储、重复执行校验逻辑:
#!/bin/bash # 自定义配置,根据你的APP修改 PRIVATE_KEY_ID="com.yourapp.bundle.privatekey" # 钥匙串中私钥的唯一标识 PRIVATE_KEY_TEMP_FILE="$PROJECT_DIR/temp_private_key.pem" # 检查钥匙串中是否已存在目标私钥,存在则直接退出 security find-generic-password -a "$PRIVATE_KEY_ID" -s "$PRIVATE_KEY_ID" > /dev/null 2>&1 if [ $? -eq 0 ]; then echo "私钥已存在于钥匙串,跳过生成流程" exit 0 fi # 无交互生成2048位RSA私钥(无需手动输入密码) openssl genpkey -algorithm RSA -out "$PRIVATE_KEY_TEMP_FILE" -pkeyopt rsa_keygen_bits:2048 # 将私钥导入钥匙串,限制仅当前APP可访问 security add-generic-password -a "$PRIVATE_KEY_ID" -s "$PRIVATE_KEY_ID" -w "$(cat "$PRIVATE_KEY_TEMP_FILE")" -T "$PRODUCT_BUNDLE_IDENTIFIER" # 删除本地临时私钥文件,防止被打包进APP rm -f "$PRIVATE_KEY_TEMP_FILE" echo "私钥生成成功并已存入钥匙串" exit 0
关键细节说明
- 仅执行一次逻辑:通过
security find-generic-password检查钥匙串中是否存在指定标识的私钥,存在则直接终止脚本,避免重复生成。 - 无交互生成私钥:去掉
-aes256参数生成不加密的私钥;如果业务要求必须加密,可添加-pass pass:${YOUR_ENCRYPT_PASSWORD}参数(建议用环境变量存储密码,不要硬编码)。 - 钥匙串权限控制:
-T "$PRODUCT_BUNDLE_IDENTIFIER"限制只有当前APP能访问该私钥,默认禁止其他应用访问,保证安全性。 - Xcode配置:把这个脚本添加到Xcode的
Build Phases->Run Script中,建议放在Compile Sources之前执行。
常见问题排查
- 权限报错:在Xcode的
Build Settings里把ENABLE_USER_SCRIPT_SANDBOXING设为NO,解除沙箱对脚本访问钥匙串的限制。 - 设备授权问题:首次在iOS设备上运行时,应用会请求钥匙串访问权限,需要在
Info.plist中添加NSKeychainUsageDescription字段,填写权限申请说明。
内容的提问来源于stack exchange,提问作者nirav
相关产品推荐
相关产品推荐

