# How to Decrypt and Analyze IMG3 and IMG4 Firmware Formats with ipsw

> Easily decrypt and analyze IMG3 and IMG4 firmware with ipsw. Use the ipsw CLI or Go packages for automated decryption and in-depth analysis of Apple firmware.

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

---

**You can decrypt and analyze Apple IMG3 and IMG4 firmware files using the `ipsw` toolkit's Go packages (`pkg/img3`, `pkg/img4`) for programmatic access or the `ipsw` CLI for command-line workflows that support automatic key lookup from public databases.**

The `ipsw` toolkit provides comprehensive support for parsing and decrypting Apple's proprietary firmware containers. Whether you are analyzing legacy **IMG3** binary tag-based formats or modern **ASN.1-based IMG4** wrappers, `ipsw` offers both low-level Go APIs and high-level CLI commands to extract and decrypt firmware components.

## Understanding IMG3 and IMG4 Firmware Formats

Apple firmware files use two primary container formats. **IMG3** is a binary tag-based structure used in older iOS devices, while **IMG4** is a newer ASN.1-encoded wrapper that contains optional Payload, Manifest, and RestoreInfo components. Both formats support encryption via **KBAG** (keybag) tags that store the AES IV and key required for decryption.

## Parsing IMG3 Files with pkg/img3

The `pkg/img3` package in `ipsw` provides a complete parser for IMG3 containers. The implementation in [`pkg/img3/img3.go`](https://github.com/blacktop/ipsw/blob/main/pkg/img3/img3.go) defines the binary structures and parsing logic.

The **Header** structure starts with a 4-byte magic (`Img3`) followed by size fields and an identifier:

```go
// pkg/img3/img3.go#L23-L34
type Header struct {
    Magic  [4]byte
    Size   uint32
    ID     uint32
    // ...
}

```

**Tags** are repeated blocks containing a header, data, and padding. Common tags include `TYPE`, `DATA`, and `KBAG`:

```go
// pkg/img3/img3.go#L36-L44
type Tag struct {
    Header TagHeader
    Data   []byte
    Pad    []byte
}

```

To parse an IMG3 file programmatically, use the `ParseImg3` function:

```go
import "github.com/blacktop/ipsw/pkg/img3"

data, err := os.ReadFile("firmware.img3")
if err != nil {
    log.Fatal(err)
}

img, err := img3.ParseImg3(data)
if err != nil {
    log.Fatal(err)
}

```

## Decrypting IMG3 Firmware Components

Decryption in `ipsw` follows a two-step process: first decrypting the **KBAG** to obtain the AES key and IV, then decrypting the actual `DATA` tag using AES-CBC.

The `DecryptKBag` function in [`pkg/img3/img3.go`](https://github.com/blacktop/ipsw/blob/main/pkg/img3/img3.go) handles KBAG decryption using a supplied GID key:

```go
// pkg/img3/img3.go#L232-L259
func DecryptKBag(kbagData []byte, gidKey []byte) ([]byte, error) {
    // Decrypts KBAG payload to reveal IV and AES key
}

```

For the complete workflow, use `DecryptWithGIDKey` which combines KBAG extraction and data decryption:

```go
decrypted, err := img3.DecryptWithGIDKey(data, gidKey)
if err != nil {
    log.Fatal(err)
}

```

Alternatively, if you already have the raw IV and key (not the GID key), use `DecryptData` directly:

```go
// pkg/img3/img3.go#L266-L291
func DecryptData(data []byte, iv []byte, key []byte) ([]byte, error) {
    // AES-CBC decryption
}

```

## Parsing and Decrypting IMG4 Files

The **IMG4** format uses ASN.1 encoding and is handled by `pkg/img4`. The top-level structure in [`pkg/img4/img4.go`](https://github.com/blacktop/ipsw/blob/main/pkg/img4/img4.go) consists of optional Payload, Manifest, and RestoreInfo components:

```go
// pkg/img4/img4.go#L52-L65
type Image struct {
    Payload      *Payload
    Manifest     *Manifest
    RestoreInfo  *RestoreInfo
}

```

Parse an IMG4 file using the `Parse` function:

```go
import "github.com/blacktop/ipsw/pkg/img4"

data, err := os.ReadFile("firmware.img4")
if err != nil {
    log.Fatal(err)
}

img4Image, err := img4.Parse(data)
if err != nil {
    log.Fatal(err)
}

```

The **IM4P** (IMG4 Payload) component contains the actual firmware binary and may include its own KBAG for encryption. Access the payload via `img4Image.Payload` and check `payload.Encrypted` to determine if decryption is required.

## Decrypting IMG4 IM4P Payloads

Decryption of IMG4 payloads is implemented in [`pkg/img4/payload.go`](https://github.com/blacktop/ipsw/blob/main/pkg/img4/payload.go). The `DecryptPayload` function performs AES-CBC decryption when provided with the correct IV and key:

```go
// pkg/img4/payload.go#L756-L768
func DecryptPayload(inputPath string, outputPath string, iv []byte, key []byte) error {
    // Reads IM4P, decrypts with AES-CBC, writes output
}

```

For in-memory decryption of payload bytes, use `DecryptPayloadBytes`:

```go
decryptedData, err := img4.DecryptPayloadBytes(payload.Data, iv, key)
if err != nil {
    log.Fatal(err)
}

```

If you need to decrypt a complete IMG4 file programmatically, combine parsing with payload decryption:

```go
// Open and parse
payload, err := img4.OpenPayload("kernelcache.im4p")
if err != nil {
    log.Fatal(err)
}

// Decrypt if necessary
if payload.Encrypted {
    decrypted, err := img4.DecryptPayloadBytes(payload.Data, iv, key)
    if err != nil {
        log.Fatal(err)
    }
    os.WriteFile("kernelcache.decrypted", decrypted, 0644)
}

```

## Using the ipsw CLI for Firmware Analysis

The `ipsw` command-line tool provides convenient access to all parsing and decryption functionality without writing Go code.

### Analyzing IMG3 Files

Inspect IMG3 metadata:

```bash
ipsw img3 info firmware.img3

```

Extract and decrypt with raw keys:

```bash

# Using concatenated IV+key

ipsw img3 extract firmware.img3 \
    --iv-key 112233445566778899aabbccddeeff0000112233445566778899aabbccddeeff

# Using separate IV and key

ipsw img3 extract firmware.img3 \
    --iv 112233445566778899aabbccddeeff00 \
    --key 00112233445566778899aabbccddeeff

```

Auto-lookup keys from theapplewiki.com:

```bash
ipsw img3 extract firmware.img3 \
    --lookup \
    --lookup-device iPhone14,2 \
    --lookup-build 20H71

```

### Analyzing IMG4 Files

Get human-readable IMG4 information:

```bash
ipsw img4 info firmware.img4

```

Output as JSON for programmatic processing:

```bash
ipsw img4 info firmware.img4 --json

```

Extract and decrypt IM4P payloads:

```bash

# With explicit keys

ipsw img4 im4p extract kernelcache.im4p \
    --iv 112233445566778899aabbccddeeff00 \
    --key 00112233445566778899aabbccddeeff \
    --output kernelcache.bin

# With automatic key lookup

ipsw img4 im4p extract kernelcache.im4p \
    --lookup --lookup-device iPhone14,2 --lookup-build 20H71

```

## Summary

- **IMG3** files use a binary tag-based structure with `KBAG` tags containing encrypted AES keys, while **IMG4** files use ASN.1 encoding with separate Payload, Manifest, and RestoreInfo components.
- The `pkg/img3` package provides `ParseImg3`, `DecryptKBag`, and `DecryptWithGIDKey` for parsing and decrypting IMG3 firmware in Go.
- The `pkg/img4` package offers `Parse`, `OpenPayload`, and `DecryptPayload` for handling IMG4 containers and IM4P payload decryption.
- The `ipsw` CLI exposes these capabilities through `ipsw img3 extract`, `ipsw img4 info`, and `ipsw img4 im4p extract`, with support for automatic key lookup via `--lookup` flags.

## Frequently Asked Questions

### What is the difference between IMG3 and IMG4 firmware formats?

IMG3 is Apple's older binary tag-based format used in earlier iOS devices, consisting of a header followed by sequential tags like `TYPE`, `DATA`, and `KBAG`. IMG4 is the modern replacement using ASN.1 encoding that wraps firmware components in a structured container with separate Payload (IM4P), Manifest, and RestoreInfo sections. Both formats support encryption via KBAG tags, but IMG4 provides more flexible metadata and is used in all modern Apple devices.

### How does ipsw handle firmware decryption without manual keys?

The `ipsw` CLI supports automatic key lookup through the `--lookup` flag, which queries the public *theapplewiki.com* database for IV and key pairs based on your specified device identifier and iOS build number. When you run commands like `ipsw img3 extract --lookup` or `ipsw img4 im4p extract --lookup`, the tool automatically retrieves the appropriate decryption keys and applies them using the underlying `DecryptWithGIDKey` or `DecryptPayload` functions.

### Can I use ipsw as a library in my own Go applications?

Yes, `ipsw` is designed as a modular Go toolkit that you can import into your own projects. The `pkg/img3` and `pkg/img4` packages provide programmatic access to parsing and decryption functions like `ParseImg3`, `DecryptData`, `Parse`, and `DecryptPayloadBytes`. You can use these to build custom firmware analysis pipelines, automated decryption services, or specialized security research tools without relying on the CLI interface.

### What encryption methods does ipsw support for firmware decryption?

`ipsw` implements AES-CBC decryption for both IMG3 and IMG4 formats. For IMG3 files, it handles KBAG decryption using either GID keys (device-specific group keys) or raw user-supplied keys via functions like `DecryptKBag` and `DecryptWithGIDKey`. For IMG4/IM4P payloads, decryption is handled by `DecryptPayload` and `DecryptPayloadBytes`, which apply AES-CBC using the IV and key extracted from the KBAG or provided manually.