07 — DRM (Widevine / FairPlay / PlayReady)
이 문서가 답하는 질문: 누가 키를 쥐고, 누가 풀어주고, 사용자는 어떻게 라이선스를 받는가? 표준: ISO/IEC 23001-7 (Common Encryption — CENC), W3C EME (Encrypted Media Extensions). 핵심 한 줄: 콘텐츠는 키 ID로 식별되는 한 키로 암호화하고, 세 DRM 시스템이 그 키를 각각 자기 방식으로 클라이언트 CDM에 전달한다.
한 줄 답 (Pyramid Top)
DRM은 **“콘텐츠 키를 절대 평문으로 클라이언트에 노출하지 않으면서 디바이스의 안전한 환경(CDM/TEE)에 전달하는 시스템”**이다. 같은 segment를 풀 수 있도록 Widevine·FairPlay·PlayReady가 *공통 암호화 (CENC)*에 합의했고, 각자의 라이선스 서버 / CDM만 다르다.
Why — 왜 DRM이 필요한가
콘텐츠 보호의 두 단계:
- 암호화 (Encryption) — 누구나 segment 파일을 받아도 평문 비디오를 못 본다.
- 키 관리 (Key Management) — 키를 허가된 사용자의 허가된 디바이스에만 전달.
암호화만 하면 부족하다 — 누가 키를 가져오면 영원히 풀린다. 키는 디바이스의 안전한 영역(CDM)에 세션 단위로만 전달되어야 한다.
DRM이 푸는 진짜 문제:
- 재배포 차단 — 평문 비디오가 disk에 떨어지지 않게.
- HDCP — HDMI 출력으로 캡처되지 않게.
- 워터마킹 — 누가 유출했는지 추적 가능하게.
- 정책 — “rental은 24시간 후 만료”, “오프라인 다운로드는 30일”, “출력은 HDR 못함” 같은 비즈니스 룰.
How — 3대 DRM 시스템
| DRM | 만든 이 | 주 디바이스 | CDM 위치 | 식별자 |
|---|---|---|---|---|
| Widevine | Android, Chrome, Firefox, Edge, Smart TV | OS/Browser | urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed | |
| FairPlay | Apple | iOS/iPadOS/macOS Safari, tvOS | iOS Secure Enclave | urn:uuid:94ce86fb-07ff-4f43-adb8-93d2fa968ca2 |
| PlayReady | Microsoft | Windows, Edge, Xbox, Smart TV (Samsung/LG) | Windows TEE | urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95 |
→ 한 OTT 서비스가 모든 디바이스를 커버하려면 셋 다 지원해야 한다.
Widevine의 보안 레벨 (가장 자주 쓰는 분류)
| Level | 키 처리 | 디코딩 | 화질 가능 |
|---|---|---|---|
| L1 | TEE 안 (ARM TrustZone, Intel SGX 등) | TEE 안 | 4K UHD / HDR 가능 |
| L2 | TEE 안 | TEE 밖 (일반 OS) | 1080p까지 |
| L3 | 일반 OS (소프트웨어) | 일반 OS | 480p~720p로 제한 |
→ Netflix 4K가 L1 디바이스에서만 보이는 이유. Chrome 브라우저는 보통 L3, Android의 대부분이 L1, iOS는 FairPlay 자체가 L1 동급.
라이선스 서버가 디바이스의 보안 레벨을 증명서로 검증하고, 정책에 따라 낮은 해상도 키만 발급할 수 있다.
보안 레벨이 결정되는 흐름
How — EME / CDM / 라이선스 흐름 (브라우저 기준)
핵심 객체
CDM은 브라우저/OS 안에 박힌 보안 모듈. 평문 키와 평문 비디오는 CDM 밖으로 안 나간다. 디코딩된 frame을 GPU로 직접 보내거나, 암호화된 video buffer만 외부에 노출한다.
라이선스 흐름 (DASH + Widevine 예)
Shaka Player에서의 설정 예
player.configure({
drm: {
servers: {
'com.widevine.alpha': 'https://widevine.example.com/license',
'com.microsoft.playready': 'https://playready.example.com/license',
'com.apple.fps.1_0': 'https://fairplay.example.com/license'
},
advanced: {
'com.widevine.alpha': {
videoRobustness: 'SW_SECURE_DECODE',
audioRobustness: 'SW_SECURE_CRYPTO'
},
'com.apple.fps.1_0': {
serverCertificateUri: 'https://fairplay.example.com/cert'
}
}
}
});
player.getNetworkingEngine().registerRequestFilter((type, request) => {
if (type === shaka.net.NetworkingEngine.RequestType.LICENSE) {
request.headers['Authorization'] = `Bearer ${userJwt}`;
}
});| 옵션 | 의미 |
|---|---|
servers.com.widevine.alpha | Widevine 라이선스 endpoint |
videoRobustness | 보안 등급 요청 (SW_SECURE_DECODE, HW_SECURE_DECODE, HW_SECURE_ALL) |
FairPlay serverCertificateUri | FairPlay는 서버 인증서를 미리 받아야 challenge 만들 수 있음 |
| RequestFilter | 라이선스 요청에 사용자 토큰 첨부 (entitlement 검증) |
How — FairPlay의 다른 점 (HLS + skd://)
FairPlay는 EME 인터페이스는 같지만 HLS-native 흐름이 있다.
HLS 매니페스트의 키 선언
#EXT-X-KEY:METHOD=SAMPLE-AES,
URI="skd://license.example.com/fps?contentId=abc",
KEYFORMAT="com.apple.streamingkeydelivery",
KEYFORMATVERSIONS="1"skd://scheme는 FairPlay 전용. iOS의 AVPlayer가 알아본다.- 라이선스 흐름은 iOS native AVAssetResourceLoaderDelegate가 처리 (브라우저 EME 흐름과 평행).
라이선스 시퀀스
| 객체 | 의미 |
|---|---|
| SPC | Server Playback Context — 클라이언트가 만든 암호화된 challenge |
| CKC | Content Key Context — 라이선스 서버가 돌려주는 암호화된 키 응답 |
| FPS Certificate | 라이선스 서버의 공개 키 인증서. 클라이언트가 SPC 만들 때 사용. |
What — CENC 두 모드 (CTR vs CBCS) 다시
CENC cenc (CTR mode)
- AES-128 in CTR mode.
- 모든 sample 전체 암호화.
- 원본 채택: Widevine, PlayReady (legacy).
- FairPlay는 지원 안 함 → iOS 재생 불가.
CENC cbcs (CBC + sample pattern)
- AES-128 in CBC mode + 1:9 패턴 (1 block 암호화 + 9 block skip).
- 부분 암호화 → CPU 부담 ↓.
- 원본 채택: FairPlay.
- Widevine, PlayReady도 지원 (2018~).
| Mode | Widevine | FairPlay | PlayReady | iOS 재생 | Android |
|---|---|---|---|---|---|
cenc (CTR) | ✅ | ❌ | ✅ | ❌ | ✅ |
cbcs (CBC) | ✅ | ✅ | ✅ | ✅ | ✅ |
→ CMAF 시대의 권장: cbcs 단일 모드. 그래야 한 번 암호화로 세 DRM 모두 + iOS.
What — DASH MPD에서의 DRM 선언
<AdaptationSet contentType="video">
<ContentProtection
schemeIdUri="urn:mpeg:dash:mp4protection:2011"
value="cbcs"
cenc:default_KID="34e5db32-8625-47cd-ba06-68fca0655a72"/>
{/* Widevine */}
<ContentProtection
schemeIdUri="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"
value="Widevine">
<cenc:pssh>AAAAVnBzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADYIARIQNOXbMoYlR826Bm...</cenc:pssh>
</ContentProtection>
{/* PlayReady */}
<ContentProtection
schemeIdUri="urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95"
value="PlayReady">
<cenc:pssh>AAAB3HBzc2gAAAAAmgTweZhAQoarkuZb4Ihflw...</cenc:pssh>
<mspr:pro>...</mspr:pro>
</ContentProtection>
{/* (FairPlay는 보통 DASH가 아니라 HLS 매니페스트에서 따로) */}
</AdaptationSet>| 요소 | 역할 |
|---|---|
default_KID | 콘텐츠 키의 ID (UUID). DRM 무관 공통 식별자. |
cenc:pssh | DRM별 Protection System Specific Header. 라이선스 요청 시 라이선스 서버가 어떤 콘텐츠인지 식별. |
mspr:pro | PlayReady Object (legacy 메타) |
PSSH 박스는 segment 안에도 들어갈 수 있고(in-band), MPD에 들어갈 수도 있다(out-of-band). 모던 디자인은 MPD에만 두는 게 일반적 — segment는 암호화된 미디어만.
What — License Server의 책임
라이선스 서버는 키 저장소 + 정책 엔진 + 인증 검증의 결합.
| 단계 | 실패 시 |
|---|---|
| 1 | 401 Unauthorized |
| 2 | 403 Forbidden (구독 만료 등) |
| 3 | 정책 위반 응답 (HDCP 부재 등) |
| 4 | 낮은 해상도 키만 발급 |
| 5 | 404 (콘텐츠 키 없음) |
| 6 | 500 |
상용 솔루션
| 제품 | DRM 지원 | 비고 |
|---|---|---|
| AWS Elemental MediaPackage + SPEKE | Widevine, FairPlay, PlayReady | AWS 통합 |
| Google Widevine Cloud | Widevine | Google direct |
| EZDRM | 셋 다 | SaaS |
| DRMtoday (castLabs) | 셋 다 | SaaS |
| Axinom DRM | 셋 다 | SaaS |
| ExpressPlay | 셋 다 + Marlin | SaaS |
→ 자체 라이선스 서버 구축은 Widevine SDK (Google과 NDA), FairPlay 인증서 (Apple Developer 신청) 모두 벤더 승인 필요. 대부분 SaaS로 우회.
What — Output Protection (HDCP, 워터마킹)
라이선스 응답에는 디코딩 후 출력에 대한 정책도 포함된다.
| 정책 | 의미 |
|---|---|
hdcpVersion: "2.2" | HDMI 출력에 HDCP 2.2 이상 요구 (UHD) |
outputControl: "DIGITAL_ONLY" | 아날로그 출력 (VGA 등) 차단 |
forensicWatermark: true | 사용자별 보이지 않는 워터마크 합성 |
secureStop: true | 세션 종료 시 키 즉시 폐기 |
→ 4K 콘텐츠는 거의 모두 HDCP 2.2 강제. 외부 모니터가 HDCP 1.4면 FHD까지 다운그레이드해서 재생.
What-if — 잘못 설계하면 어떻게 깨지는가
| 증상 | 원인 | 처방 |
|---|---|---|
| iOS는 재생 안 됨, Chrome만 OK | CTR(cenc) 사용 | CBCS로 재패키징 |
| Android에서 보안 등급 낮아 4K 안 나옴 | Widevine L3 디바이스 | 정책에 L1 강제 또는 1080p로 cap |
| 라이선스 서버 5xx 폭주 | JWT 검증이 매번 DB hit | 캐시 (사용자별 entitlement 5분 캐시) |
| 세션 만료 후 재생 멈춤 | 라이선스 expiresIn 짧음 | persistent license + renewal |
| PSSH가 in-band인데 매니페스트만 보호 | segment 안에 PSSH 노출 | MPD에 옮기거나 제거 |
| 라이선스 challenge에 사용자 정보 없음 | URL 쿼리만 사용 | header에 JWT 첨부 (request filter) |
| PlayReady만 안 됨 | Soap envelope 미생성 | PlayReady 요청은 SOAP/XML, REST와 다름 — 라이선스 SaaS의 PlayReady proxy 사용 |
| content key가 leaked | server-side test 환경 키가 prod와 동일 | 환경별 KEK 분리 + key rotation |
Insight — 흥미로운 이야기
“DRM은 제거 가능 한 적이 있다”
실제로 Widevine L3는 완전 소프트웨어다 → 분석된 적이 있다. 그래서 L3 디바이스는 720p로 cap. L1은 TEE 안에서 동작 — 현재까지 깨진 적이 없다 (Apple Secure Enclave, ARM TrustZone, Intel SGX). DRM의 안전성은 수학적이 아니라 하드웨어 신뢰에 의존한다.
“FairPlay 인증서를 Apple에서 받으려면 회사로 신청해야 한다”
Apple Developer 계정만으론 안 된다. Apple FairPlay Streaming Deployment Package를 따로 신청해야 하고, 검토에 수 주~수 개월. 이게 OTT 서비스가 FairPlay 직접 운영보다 DRM SaaS를 쓰는 큰 이유.
“DRM 라이선스 비용도 무시 못 한다”
라이선스 SaaS는 월 단위 라이선스 수로 과금. 1억 명에게 1편씩 보여주면 1억 라이선스. 단가 100k*. 그래서 라이선스 유효 기간을 길게(30일~1년) 가져가는 정책이 일반적.
“클라이언트 동시 재생 제한도 라이선스 서버가 결정”
“최대 2개 디바이스에서 동시 시청” 같은 정책은 라이선스 서버에서 active session을 카운트하고 초과 시 기존 세션을 invalidate. Netflix가 동시 시청 제한을 늘렸다 줄였다 하는 게 라이선스 서버 로직 변경.
“DRM이 없는 비디오 = ‘시청은 가능하지만 추적 불가’”
워터마크 같은 forensic 기능은 DRM 없이도 가능 (서버에서 사용자별 다른 비트 합성). 그러나 재배포 차단은 암호화 + DRM 없이는 어렵다. 그래서 OTT는 DRM이 콘텐츠 라이선스 계약의 조건인 경우가 많다 — Hollywood 메이저 6사가 L1 강제를 요구.
한 단락 요약 + Mermaid
DRM은 콘텐츠 키를 디바이스의 안전 영역(CDM)에만 전달하는 시스템이다. Widevine·FairPlay·PlayReady가 같은 segment(CENC
cbcs)를 풀 수 있게 합의했고, 각자의 라이선스 서버 / CDM 흐름만 다르다. Apple FairPlay는 HLS-native skd:// 스킴, 나머지는 EME 표준 흐름. 4K는 거의 항상 L1 + HDCP 2.2를 요구한다.
→ 다음 파일 08-player-engines.md: 이 모든 표준을 실제로 어떤 코드가 처리하는가.