Mobile Development 21 min read

DRM (FairPlay) Implementation and Key Management on iOS

The article explains iOS FairPlay DRM implementation, detailing the encryption workflow, SPC/CKC exchange, and key terminology, and compares two key‑management methods—AVAssetResourceLoader and the newer AVContentKeySession—while covering usage scenarios such as on‑demand, pre‑warming, offline playback, persistable keys, and video downloading via AVAssetDownloadTask.

Sohu Tech Products
Sohu Tech Products
Sohu Tech Products
DRM (FairPlay) Implementation and Key Management on iOS

Digital Rights Management (DRM) protects video content by encrypting the media, securely storing and transmitting encryption keys, and allowing content providers to define usage rules.

DRM workflow : the video is encrypted with a symmetric algorithm (typically AES‑128). The encrypted stream is delivered to the client, which requests a decryption key from a DRM server. After authentication, the server returns the content key (CKC) and licensing rules, which the client’s Content Decryption Module (CDM) uses to decode the video.

Common DRM schemes include FairPlay on Apple platforms. FairPlay uses HLS + fMP4 packaging and supports specific codec tags (hvc1 for HEVC). The .m3u8 playlist contains an #EXT‑X‑KEY tag indicating encrypted segments.

FairPlay playback flow :

User taps play, AVPlayer receives a .m3u8 URL.

AVPlayer parses the playlist, detects the #EXT‑X‑KEY tag.

The system requests Secure Playback Context (SPC) data.

The SPC is sent to the key server, which returns a Content Key Context (CKC) containing the decryption key.

AVFoundation uses the CKC to decrypt and render the video.

Key terminology :

SPC – encrypted request data sent to the server.

CKC – encrypted response containing the decryption key and its validity.

KSM – backend key‑security module.

CDM – client‑side decryption module integrated with AVPlayer.

Two iOS key‑management approaches :

1. AVAssetResourceLoader

Implement AVAssetResourceLoaderDelegate and intercept key requests during playback. The delegate obtains SPC, sends it to the server, receives CKC, and supplies it back to the loading request.

loaderDelegate = [[SofaAssetLoaderDelegate alloc] init];
loaderDelegate.fpCerData = self.fpCerData;
loaderDelegate.fpRedemptionUrl = fpRedemption;
loaderDelegate.asset = self.urlAsset;
[[self.urlAsset resourceLoader] setDelegate:loaderDelegate queue:globalNotificationQueue()];
// ... handling of SPC/CKC inside delegate methods ...

2. AVContentKeySession (recommended since iOS 11.2)

Create a session, set its delegate, and let the system call back when a key is needed. This decouples key acquisition from playback and supports pre‑warming and offline keys.

_keyQueue = dispatch_queue_create("com.sohuvideo.contentkeyqueue", DISPATCH_QUEUE_SERIAL);
self.keySession = [AVContentKeySession contentKeySessionWithKeySystem:AVContentKeySystemFairPlayStreaming];
[self.keySession setDelegate:self queue:_keyQueue];

Usage scenarios :

On‑demand playback : request SPC/CKC only after the user taps play.

Pre‑warming : predict the next asset and request its key in advance to reduce start‑up latency.

Offline playback : request a persistable content key, store it locally, and later use it with AVAssetDownloadTask to download the video for offline viewing.

Persistable keys have two lifetimes: a long storage duration (e.g., 30 days) and a short playback duration (e.g., 48 hours). When the playback‑duration key expires, the system calls contentKeySession:didUpdatePersistableContentKey:forContentKeyIdentifier: to refresh the stored key.

Downloading videos with AVAssetDownloadTask

Create an AVAssetDownloadURLSession , make a download task, and implement AVAssetDownloadDelegate callbacks to monitor progress, handle completion, and move the downloaded .movpkg bundle to a desired location.

let assetDownloadURLSession = AVAssetDownloadURLSession(configuration: backgroundConfiguration,
    assetDownloadDelegate: self, delegateQueue: OperationQueue.main)
let downloadTask = assetDownloadURLSession.makeAssetDownloadTask(asset: asset.urlAsset,
    assetTitle: asset.stream.name, assetArtworkData: nil, options: nil)
downloadTask?.resume()

For multi‑track HLS streams, use AVAggregateAssetDownloadTask to select specific media selections and set a minimum bitrate.

let task = assetDownloadURLSession.aggregateAssetDownloadTask(with: asset.urlAsset,
    mediaSelections: [preferredMediaSelection], assetTitle: asset.stream.name,
    assetArtworkData: nil,
    options: [AVAssetDownloadTaskMinimumRequiredMediaBitrateKey: 265_000])
task?.resume()

Reference links include Apple’s FairPlay Streaming documentation and WWDC sessions on AVContentKeySession best practices and offline HLS playback.

iOSEncryptionDRMAVFoundationContentKeyFairPlayVideoStreaming
Sohu Tech Products
Written by

Sohu Tech Products

A knowledge-sharing platform for Sohu's technology products. As a leading Chinese internet brand with media, video, search, and gaming services and over 700 million users, Sohu continuously drives tech innovation and practice. We’ll share practical insights and tech news here.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.