# How to Extract, Analyze, and Patch OTA Updates with ipsw

> Discover how to extract analyze and patch OTA updates using ipsw. Learn to download inspect files and apply RSR patches effectively with this powerful tool.

- Repository: [blacktop/ipsw](https://github.com/blacktop/ipsw)
- Tags: how-to-guide
- Published: 2026-02-26

---

**ipsw treats OTA updates as ZIP containers containing a post.bom manifest and encrypted payloads, providing CLI commands and Go libraries to download, inspect, extract files, and apply RSR patches using raw image diffing.**

The `blacktop/ipsw` repository provides a comprehensive toolkit for working with Apple firmware files. Whether you need to extract, analyze, and patch OTA updates with ipsw, the tool offers both command-line interfaces and Go libraries to handle encrypted payloads, cryptex volumes, and Rapid Security Response patches.

## Understanding the OTA Update Structure

Apple OTA updates are ZIP archives containing a `post.bom` manifest, encrypted payload files (often AEA-encrypted IMG4), and optionally **cryptex** volumes for Rapid Security Response patches. The `ipsw` tool models this structure in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go), where the `OTA` type provides methods to access the ZIP contents, decrypt payloads, and parse the BOM manifest.

## Downloading and Decrypting OTA Updates

The `ipsw download ota` command retrieves OTA files from Apple's servers. When dealing with encrypted updates, `ipsw` handles **AEA** (Apple Encrypted Archive) decryption automatically.

### Handling AEA Encryption

In [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go), the `Open()` function creates an `*ota.OTA` object and calls `ResolveAEAKeyFromFlags` to obtain decryption keys from Apple's servers or a local [`ota_fcs_keys.json`](https://github.com/blacktop/ipsw/blob/main/ota_fcs_keys.json) database. This lazy-loading approach ensures the ZIP structure is parsed before attempting decryption of the payload.

## Analyzing OTA Metadata

To inspect update metadata without extracting files, use `ipsw ota info`. This command leverages the `ota.Info()` method in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go) to parse the embedded `Info.plist` and `post.bom` manifest, returning version, build numbers, supported devices, and signed components.

## Extracting Files from OTA Updates

The extraction pipeline supports individual files, pattern matching, and cryptex volume handling.

### Listing and Extracting Individual Files

The `Files()` method in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go) returns a filtered slice of `zip.File` entries based on the `post.bom` manifest. To extract a specific file, open it via `o.Open(name, decompress)` and copy the bytes to your destination.

### Working with Cryptex Volumes

For Rapid Security Response updates, `ipsw` handles **cryptex** volumes containing `cryptex-app` and `cryptex-system-*` DMGs. The `ExtractFromCryptexes` method in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go) walks these volumes and extracts files matching a regex pattern. Low-level cryptex unpacking logic resides in [`pkg/ota/aa.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/aa.go).

### Pattern-Based Extraction

The `RemoteExtract` function (approximately lines 115-140 in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go)) enables regex-based extraction across the entire payload. This function iterates over payload files, runs `Parse()` (which uses Apple's `aa` binary when available, otherwise a Go implementation), and writes matches to the destination folder.

## Patching OTA Updates with RSR (Rapid Security Response)

Rapid Security Response updates patch existing OTA files without requiring full system reinstalls. The `ipsw ota patch rsr` command applies these differential updates to AppOS and SystemOS cryptexes.

### Understanding the RSR Patching Process

RSR patches use raw image diffing to modify existing DMG files. The process extracts the original `cryptex-app` and `cryptex-system-*` DMGs from the base OTA, applies binary diffs from the RSR update using `ridiff.RawImagePatch`, and writes the patched DMGs back to disk.

### Applying Patches with ipsw ota patch rsr

The command implementation in [`cmd/ipsw/cmd/ota/ota_patch_rsr.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipsw/cmd/ota/ota_patch_rsr.go) orchestrates the workflow. It calls `ridiff.RawImagePatch` (located in `pkg/ota/ridiff`) to perform the actual binary patching, handling both the AppOS and SystemOS cryptexes in a single operation.

## Programmatic Usage with Go

The `ipsw` library exposes the OTA pipeline as a Go API for integration into custom tools.

### Listing OTA Files

```go
package main

import (
	"fmt"
	"log"

	"github.com/blacktop/ipsw/pkg/ota"
)

func main() {
	// Open (auto-decrypt if needed)
	o, err := ota.Open("myOTA.zip", nil)
	if err != nil {
		log.Fatal(err)
	}
	// Print all entries
	for _, f := range o.Files() {
		if f.IsDir() {
			continue
		}
		fmt.Println(f.Name())
	}
}

```

The `Files()` method in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go) returns the filtered `zip.File` slice based on the `post.bom` manifest.

### Extracting dyld_shared_cache Files

```go
package main

import (
	"log"
	"path/filepath"

	"github.com/blacktop/ipsw/pkg/ota"
)

func main() {
	o, _ := ota.Open("myOTA.zip", nil)
	info, _ := o.Info()
	output := filepath.Join(".", info.GetFolder())
	_ = o.ExtractFromCryptexes(`dyld_shared_cache.*`, output) // uses RIDIFF10 cryptexes
}

```

`ExtractFromCryptexes` walks cryptex volumes and extracts files matching the provided regex.

### Patching RSR Updates Programmatically

```go
package main

import (
	"log"
	"path/filepath"

	"github.com/blacktop/ipsw/pkg/ota"
	"github.com/blacktop/ipsw/pkg/ota/ridiff"
)

func main() {
	basePath := "BaseOTA.zip"
	rsrPath := "RSR_OTA.zip"

	// Parse base OTA to locate the DMGs
	baseInfo, _ := ota.ParseInfo(basePath)
	appDMG, _ := baseInfo.GetAppOsDmg()
	sysDMG, _ := baseInfo.GetSystemOsDmg()

	// Patch app cryptex
	if err := ridiff.RawImagePatch(appDMG, rsrPath, appDMG+"_patched.dmg", 0); err != nil {
		log.Fatal(err)
	}
	// Patch system cryptex (optionally filter architectures)
	if err := ridiff.RawImagePatch(sysDMG, rsrPath, sysDMG+"_patched.dmg", 0); err != nil {
		log.Fatal(err)
	}
}

```

This mirrors the CLI workflow in [`cmd/ipsw/cmd/ota/ota_patch_rsr.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipsw/cmd/ota/ota_patch_rsr.go), using `ridiff.RawImagePatch` to apply binary diffs.

## Summary

- **ipsw** models OTA updates as ZIP archives containing `post.bom` manifests and encrypted payloads, handling AEA decryption automatically via [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go).
- The **download** phase retrieves updates and resolves decryption keys using `ResolveAEAKeyFromFlags`, supporting both remote Apple key servers and local [`ota_fcs_keys.json`](https://github.com/blacktop/ipsw/blob/main/ota_fcs_keys.json) databases.
- **Analysis** commands like `ipsw ota info` leverage the `Info()` method to parse metadata without extraction, reading embedded plists and BOM manifests.
- **Extraction** supports individual files, regex patterns via `RemoteExtract`, and cryptex volumes through `ExtractFromCryptexes`, with low-level handling in [`pkg/ota/aa.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/aa.go).
- **RSR patching** applies differential updates to AppOS and SystemOS cryptexes using `ridiff.RawImagePatch` in `pkg/ota/ridiff`, enabling rapid security fixes without full OS reinstalls.

## Frequently Asked Questions

### How does ipsw handle AEA encryption for OTA files?

`ipsw` automatically detects AEA encryption headers when opening OTA files via `ota.Open()`. The tool calls `ResolveAEAKeyFromFlags` to fetch decryption keys from Apple's servers or a local [`ota_fcs_keys.json`](https://github.com/blacktop/ipsw/blob/main/ota_fcs_keys.json) database, then transparently decrypts the payload during extraction operations.

### What is the difference between regular OTA extraction and cryptex extraction?

Regular OTA extraction pulls files directly from the main payload ZIP using the `post.bom` manifest. Cryptex extraction specifically handles **Rapid Security Response** volumes containing `cryptex-app` and `cryptex-system-*` DMGs. The `ExtractFromCryptexes` method in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go) walks these specialized volumes to extract patched system files.

### Can I patch an existing OTA with a newer RSR update using the Go library?

Yes, the `pkg/ota/ridiff` package exposes `RawImagePatch` for programmatic RSR patching. You parse the base OTA to locate AppOS and SystemOS DMGs, then apply the RSR diff using `ridiff.RawImagePatch(baseDMG, rsrOTA, outputPath, flags)`. This mirrors the `ipsw ota patch rsr` CLI command implemented in [`cmd/ipsw/cmd/ota/ota_patch_rsr.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipsw/cmd/ota/ota_patch_rsr.go).

### Where does ipsw store decryption keys for OTA files?

`ipsw` checks for AEA decryption keys in a local JSON database named [`ota_fcs_keys.json`](https://github.com/blacktop/ipsw/blob/main/ota_fcs_keys.json) before querying Apple's remote key servers. The `ResolveAEAKeyFromFlags` function in [`pkg/ota/ota.go`](https://github.com/blacktop/ipsw/blob/main/pkg/ota/ota.go) handles this resolution logic, caching keys locally to avoid repeated network requests for the same firmware files.