iOS 跨平台代码签名工具——Zsign

iOS 跨平台代码签名工具——Zsign

在软件开发过程中,尤其是iOS应用的发布,代码签名是至关重要的环节。今天,我要向大家推荐一个开源项目——Zsign,它是一个快速、多平台的代码签名工具,支持iOS 12+以及Linux、macOS和Windows系统。

项目介绍

当你还在烦恼如何让使用Windows系统的产品、测试进行苹果重签名打包时,还在烦恼如何突破codesign重签名局限Mac系统时,还在烦恼如何openssl签名原理复杂时,那么希望zsign签名可以帮助到你!
zsign项目地址: https://github.com/zhlynn/zsign

编译环境

本文将介绍在Linux编译使用,Windows环境可参照开源项目教程⭐️⭐️⭐️
操作系统:CentOS7
Python版本:Python3.8

部署zsign(CentOS7)

1.安装

yum install git 
git clone https://github.com/zhlynn/zsign.git
cd zsign
chmod +x INSTALL.sh
./INSTALL.sh

2.编译

mkdir build
cd build
cmake ..
make

3.配置.base_profile(可选)

// 1.编辑
vim .base_profile
// 1.1 添加指定路径
export PATH
export PATH=$PATH:/zsign/build

// 2.更新
source .base_profile

// 3.验证
zsign -v
// 3.1 输出结果
version: 0.5

zsign用法

Usage: zsign [-options] [-k privkey.pem] [-m dev.prov] [-o output.ipa] file|folder

options:
-k, --pkey           Path to private key or p12 file. (PEM or DER format)
-m, --prov           Path to mobile provisioning profile.
-c, --cert           Path to certificate file. (PEM or DER format)
-d, --debug          Generate debug output files. (.zsign_debug folder)
-f, --force          Force sign without cache when signing folder.
-o, --output         Path to output ipa file.
-p, --password       Password for private key or p12 file.
-b, --bundle_id      New bundle id to change.
-n, --bundle_name    New bundle name to change.
-r, --bundle_version New bundle version to change.
-e, --entitlements   New entitlements to change.
-z, --zip_level      Compressed level when output the ipa file. (0-9)
-l, --dylib          Path to inject dylib file.
-w, --weak           Inject dylib as LC_LOAD_WEAK_DYLIB.
-i, --install        Install ipa file using ideviceinstaller command for test.
-q, --quiet          Quiet operation.
-v, --version        Show version.
-h, --help           Show help.

1.显示 mach-o 和 codesignature 段信息

./zsign demo.app/execute

2.使用 p12 和 mobileprovisioning 文件对文件夹进行签名(使用缓存)。

./zsign -k dev.p12 -p 123 -m dev.prov -o output.ipa demo.app -z 9

3.更改 bundle id 和 bundle name

./zsign -k dev.p12 -p 123 -m dev.prov -o output.ipa -b 'com.tree.new.bee' -n 'TreeNewBee' demo.ipa -z 9

4.设置证书配置文件

./zsign -k dev.p12 -p 123 -m dev.prov -o output.ipa -e entitlements.plist demo.app -z 9

踩坑之旅

1.生成的ipa文件大小是原ipa文件的两倍左右。

解决:执行命令中加入-z 9来设置输出ipa文件时的压缩级别

2.使用通配符证书重签名后iOS下载文件夹报错

	// 确定URL
    NSString *urlStr = @"xxx";
    urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL *url = [NSURL URLWithString:urlStr];
    
    // 确定request
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:0 timeoutInterval:2.0f];
    NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.app.backgroundSession"];
    configuration.discretionary = YES;
    // 确定会话
    NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];;
    
    // 由会话生成任务
    NSURLSessionDownloadTask *downloadTask = [session downloadTaskWithURL:url];
    [downloadTask resume];

报错信息:deny(1) file-write-unlink xxx/Library/Caches/com.apple.nsurlsessiond/Downloads/xxx*/aaa.file
原因:通配符证书重签名后的application-identifier为证书带星号的APPID,所以导致找不到指定下载路径。
解决:执行命令中加入-e entitlements.plist来改变application-identifier

3.如何创建entitlements.plist文件

xml格式如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>application-identifier</key>
        <string>xxxxxxxxxx.com.xxx.xxx</string>
        <key>com.apple.developer.team-identifier</key>
        <string>xxxxxxxxxx</string>
        <key>get-task-allow</key>
        <false/>
        <key>keychain-access-groups</key>
        <array>
            <string>xxxxxxxxxx.com.xxx.xxx</string>
        </array>
    </dict>
</plist>

其中xxxxxxxxxx.com.xxx.xxx要换成ipa标识(就是证书ID+BundleID),其中xxxxxxxxxx就是你的证书ID,后面部分是bundleID

4.通过python解析获取证书ID与应用BundleID,从而创建entitlements.plist文件

import plistlib
# 检查BundleId信息
def checkBundleIdInfo(self):
	infoFilePath = os.path.join(appTempPath, "Info.plist")
	if os.path.exists(infoFilePath):
		with open(infoFilePath, 'rb') as fp:
			plist_data = plistlib.load(fp)
			# 应用原ipa的bundleId,如果需要修改bundleId重签,直接使用签名的bundleId
			bundleId = plist_data["CFBundleIdentifier"]
			print(bundleId)
			
# 读取重签的证书文件
def readMobileprovision(filePath):
	with open(filePath, 'rb') as f:
		data = f.read()
		start = data.find(b"<?xml")
		end = data.find(b"</plist>") + len(b"</plist>")
		plistData = data[start:end]
		return data, plistlib.loads(plistData)

# 创建entitlements.plist文件
def createEntitlementsPlist(self):
	data, plistData = readMobileprovision(mpPath)
	entitlementsData = plistData["Entitlements"]
	if "com.apple.developer.team-identifier" in entitlementsData:
		# 证书ID
		teamId = entitlementsData["com.apple.developer.team-identifier"]
		entitlementsData["application-identifier"] = teamId + "." + bundleId
	plistData["Entitlements"] = entitlementsData
	# 生成entitlements.plist文件存放路径
	entitlementsPath = os.path.join(tempFileDir, "entitlements.plist")

	with open(self.entitlementsPath, 'wb') as f:
		plistlib.dump(entitlementsData, f)

其中appTempPath是ipa解压后Payload/xxx路径,mpPath是重签名使用的xxx.mobileprovision路径

5.应用设置Product Name为中文,解压后乱码怎么处理?(python)

import zipfile
def unzipFile(sourceFile, outputPath):
	"""
	解压文件
	:param sourceFile: 来源文件路径
	:param outputPath: 输出路径
	:return: 返回解压后所有文件列表
	"""
	zipFileList = []
	with zipfile.ZipFile(sourceFile, 'r') as zip_ref:
		for file_info in zip_ref.infolist():
			# 解决中文文件名乱码问题
			file_info.filename = file_info.filename.encode('cp437').decode('utf-8')
			# print(file_info.filename)
			zipFileList.append(file_info.filename)
			zip_ref.extract(file_info, outputPath)
	return zipFileList

⭐️如果对你有用的话,希望可以点点赞,感谢了⭐️

欢迎学习交流,本人也编写了Python版本重签工具,后续开源会分享出来,如有需要可交流学习。

  • 18
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wu.Nim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值