| Crates.io | zsign-rs |
| lib.rs | zsign-rs |
| version | 0.1.1 |
| created_at | 2025-12-29 18:43:15.894252+00 |
| updated_at | 2025-12-29 19:20:45.165722+00 |
| description | Cross-platform iOS code signing library - Rust port of zsign |
| homepage | https://github.com/jveko/zsign-rs |
| repository | https://github.com/jveko/zsign-rs |
| max_upload_size | |
| id | 2011094 |
| size | 354,138 |
A Rust implementation of zsign — a cross-platform iOS code signing tool.
Note: This is a learning project porting the original C++ implementation to Rust. It aims to provide the same functionality while leveraging Rust's safety guarantees and modern tooling.
zsign-rs signs iOS application packages (IPA files) and Mach-O binaries on macOS, Linux, and Windows. It provides an alternative to Apple's official codesign utility, enabling iOS app signing outside of the macOS ecosystem.
.app folders and nested bundles (frameworks, extensions).p12) and PEM supportzsign-rs/
├── crates/
│ ├── zsign/ # Core library
│ │ ├── builder # High-level signing API (ZSign)
│ │ ├── bundle # App bundle handling, CodeResources generation
│ │ ├── codesign # Code signature structures (CodeDirectory, SuperBlob)
│ │ ├── crypto # Certificate parsing, CMS signature generation
│ │ ├── ipa # IPA archive extraction and creation
│ │ └── macho # Mach-O binary parsing and signing
│ └── zsign-cli/ # Command-line interface
| Module | Description |
|---|---|
macho |
Parses Mach-O binaries, handles FAT archives, extracts load commands and segments |
codesign |
Builds CodeDirectory blobs with page hashes, assembles SuperBlob containers |
crypto |
Loads certificates/keys, generates CMS signatures with Apple-specific attributes |
bundle |
Traverses app bundles, generates CodeResources plist with file hashes |
ipa |
Extracts and creates IPA archives (ZIP format) |
builder |
High-level ZSign API orchestrating the signing workflow |
The signing process follows Apple's code signature format:
Payload/
└── App.app/
├── Info.plist
├── App (executable)
├── embedded.mobileprovision
├── Frameworks/
│ └── SomeFramework.framework/
└── PlugIns/
└── Extension.appex/
Bundles are signed depth-first (nested bundles before containers).
For each bundle, a _CodeSignature/CodeResources plist is created containing SHA-1 and SHA-256 hashes of all resource files.
For each executable:
SuperBlob (0xfade0cc0)
├── CodeDirectory SHA-1 (slot 0x0000)
├── Requirements (slot 0x0002)
├── Entitlements XML (slot 0x0005)
├── Entitlements DER (slot 0x0007)
├── CodeDirectory SHA-256 (slot 0x1000)
└── CMS Signature (slot 0x10000)
The SuperBlob is written to the __LINKEDIT segment, and the LC_CODE_SIGNATURE load command is updated.
use zsign::{ZSign, SigningCredentials};
// Load credentials from PKCS#12
let p12_data = std::fs::read("certificate.p12")?;
let credentials = SigningCredentials::from_p12(&p12_data, "password")?;
// Sign an IPA
ZSign::new()
.credentials(credentials)
.provisioning_profile("app.mobileprovision")
.sign_ipa("input.ipa", "output.ipa")?;
zsign-cli sign \
--cert certificate.p12 \
--password "password" \
--provision app.mobileprovision \
--output signed.ipa \
input.ipa
# Build all crates
cargo build --release
# Run tests
cargo test
# Generate documentation
cargo doc --open
This project serves as a learning exercise for:
| Concept | Implementation |
|---|---|
| Mach-O Parsing | macho::parser — Load commands, segments, FAT headers |
| Code Hashing | codesign::code_directory — Page hashing, special slots |
| Blob Structures | codesign::superblob — Apple's nested blob format |
| DER Encoding | codesign::der — Entitlements plist to DER conversion |
| CMS Signatures | crypto::cms — Apple-specific signed attributes |
| Certificate Handling | crypto::cert — PKCS#12, PEM, X.509 parsing |
This project is licensed under the MIT License — see the original zsign project.