Vous êtes sur la page 1sur 14

Common Encryption API for Widevine DRM

Version1.5

History

Date Changes

10/08/2014 Updatedtestplayerandcontenturls.

07/30/2013 UpdatedKeyId(tracks.key_id).Typeis128bitbinaryreturnedasBase64
encodedstring.
UpdatedContentId.TypeisbinaryspecifiedasaBase64encodedstring.
Sizecannotexceed1024bytes.

08/02/2013 ChangesingleWidevinePSSHtoanarraycontainingWidevineand
PlayReady.Newfieldinresponseiscalledcontent_protection.

03/21/2014 Addnewfieldstosupportlivestreamingwithkeyrotation.
first_crypto_period_index
crypto_period_count

01/13/2015 AddedsectiondescribinginsertingaPSSHintoaMPD
UpdateddemoplayersectionwithWidevineShakaPlayerlinks

04/21/2015 Updatedsignaturerequirements

01/22/2016 Addeddrm_typesarraytotheencryptionrequesttosupportPlayReady.

02/29/2016 Addcrypto_period_seconds.

06/28/2016 UpdatedWidevine
proto
.

2016Google,Inc.AllRightsReserved.Noexpressorimpliedwarrantiesareprovidedforherein.Allspecificationsaresubjectto
changeandanyexpectedfutureproducts,featuresorfunctionalitywillbeprovidedonanifandwhenavailablebasis.Notethatthe
descriptionsofGooglespatentsandotherintellectualpropertyhereinareintendedtoprovideillustrative,nonexhaustiveexamples
ofsomeoftheareastowhichthepatentsandapplicationsarecurrentlybelievedtopertain,andisnotintendedforuseinalegal
proceedingtointerpretorlimitthescopeormeaningofthepatentsortheirclaims,orindicatethataGooglepatentclaim(s)is
materiallyrequiredtoperformorimplementanyofthelisteditems.


GoogleConfidential Page2of14
Introduction
ThisdocumentspecifiesaninterfaceforaddingsupportforGooglesWidevineencryptiontoa
videoprocessingsystem.Theinterfaceallowstheencryptionprocesstorequestandreceive
theWidevineheaderandencryptionkey.

Description
TheencryptionprocesssendsanHTTP(s)requesttotheKeyserver.Therequestcontainsthe
uniquecontentidentifier(ContentId).TheContentIdisownedbytheencryptionprocess.The
KeyserverwillrespondwithProtectionSystemSpecificHeader(PSSH)dataforWidevineand
ContentKey(s)thatareassociatedwiththeContentId.
AllBase64encodedstringsusethestandardencodingspecifiedinRFC4648.
WidevineSystemIDforthePSSH
edef8ba979d64acea3c827dcd51d21ed
DASHMPDContentProtectiontype: widevine

Details
Authentication
Theprotocoldescribedinthisdocumentssupportstheabilityfortheclientandserverto
optionally
signthemessage.Themethoddescribedhereistheclientwillsigntherequestby
usingtheclientsAESkeyandWidevinewillsigntheresponseusingWidevinesRSAkey.

Request
TherequestisanHTTPPOSTrequesttotheKeyServerURL.
TheposteddataisaJSONformatted( optionallysigned
)requestwiththefollowingsyntax:

{
request:<message>,
signature:<signature>,
signer:<signername>
}

Name Value Description

request Base64encodedstring. Requiredfield.


Theactualmessage.Thisisaserialized
JSONmessagecontainingtherequestor
theresponse.Themessageisintheclear.

signature Base64encodedstring. Optionalfield.


RFC4648 RequiredforaccesstoWidevineCloud


GoogleConfidential Page3of14
LicenseService.

AESCBCencryptionoftheSHA1hashof
<message>.

signer string Required.


Identifiestheentitysendingthemessage.

Theclear<message>isaJSONformattedstringcontainingthecontentidandthetracktypes.
Acontentmayhaveoneormoretracktypes,forexample,theaudiotrackmaybeencrypted
withadifferentkeythanthevideotrack.OrthecontentmayhaveanSDvideotrackandanHD
videotrackencryptedwithdifferentkeys.

{
"content_id":"vid0000001",
policy:test_policy,
"tracks":[
{
type:HD
},
{
type:SD
},
{
type:AUDIO,
}
],
drm_types:[
{
WIDEVINE,
},
],
}

Name Value Description

type Oneof: Required.


HD,SD,AUDIO Labeltoidentifythetracktype.ItsOKfor
(maynotbelimitedto multiplerequeststospecifythesametracktype.
thissetoftypes) Inthiscase,thesamekeyidandkeyisreturned
foreachtrackofthesametype.

policy string Optional.


GoogleConfidential Page4of14
Ascii,maxsize=1024 Nameofapreviouslystoredpolicytouseforthis
bytes. content.Thepolicycontainsplaybackduration
informationandoutputprotectioninformationfor
SD,HDandAUDIO.If<policy>isnotspecified,
thecontentprovidermustprovideallpolicy
attributesatthetimeoflicenseacquisition.

content_id Base64encodedstring Required.


Uniqueidentifierofthecontent.Thecontent_id
Binary,maxsize=1024 willbeavailableinthelicenserequest.
bytes.

token Optionalbase64 Ifpresent,the72bytetokenfromaWidevine


encodedstring. keybox.Contentkeysintheresponsewillbe
AESor3DESencryptedusingthedevicekey
associatedwiththistoken,andthustheresponse
willonlyusablebyadevicewiththatkeybox.

rsa_public_key OptionalRSApublic Ifpresent,arandomsession_keyencryptedwith


keyinBase64 thispublickeywillbeincludedintheresponse.
DERencodedPKCS#1 ContentkeysintheresponsewillbeAESECB
format. encryptedwiththesessionkey.

first_crypto_period_index 32bitunsignedint Usedforkeyrotationonly.


Thetimevalueforthefirstkeyperiodforwhich
keysarerequested,dividedbytheperiod
duration.Perhapsepochormediatime.

crypto_period_count 32bitunsignedint Usedforkeyrotationonly.


Numberofkeysrequested.

crypto_period_seconds 32bitunsignedint Usedforkeyrotationonly.


Numberofsecondsineachcryptoperiod.

drm_types Optionalenumerated Usedtorequestpsshdataconformingto


drmtypeidentifier. nonwidevinedrm.

Signing the request


GeneratetheJSONstring.
Json::StyledWriterwriter
std::stringclear_message=writer.write(root)

Signthemessage.
GenerateSHA1hashofthemessage.Resultis20bytesstring.
Encryptthe20bytehash.
ForAES:CBC,PKCS5padding
ForRSA:RSAPSS,PKCS1.5padding,Saltlength=20.


GoogleConfidential Page5of14
Multiple requests using the same Content Id with different track types.
ItispossiblefortheclienttosendmultiplerequestsforcontentkeyswiththesamecontentId
(c_id))butwithdifferenttracktypes.Forexample,
request#1:contentId=CID,tracktype=SD.
request#2:contentId=CID,tracktype=AUDIO.

Inthiscase,theKeyServerwillreturnaresponseforeachrequestasfollows:
response#1:status=OK,contentId=CID,keyId=KID_1,contentkey=CKey_1,
tracktype=SD
response#2:status=OK,contentId=CID,keyId=KID_2,contentkey=CKey_2,
tracktype=AUDIO.

Multiple requests using the same Content Id with same track types.
IfmultiplerequestsaresentwiththesamecontentIdandsametracktype,thefirstresponse
willcontainthesamekeyIdandcontentkey.Thesecondresponsewillalsosucceedandfield
indicatingalreadyused.
request#1:contentId=CID,tracktype=SD.
request#2:contentId=CID,tracktype=SD.

Inthiscase,theKeyServerwillreturnaresponseforeachrequestasfollows:
response#1:status=OK,contentId=CID,keyId=KID_1,contentkey=CKey_1,
tracktype=SD.
response#2:status=OK,contentId=CID,keyId=KID_1,contentkey=CKey_1,
tracktype=SD,already_used=true.

Response
Ifsigned,theresponseisaJSONformattedstring.
{
response:<message>,
signature:<signature>
}

Where<message>isaJSONformattedstring.Foreachtracktypeintherequest,thereisa
keyandkey_idintheresponse..

{
"status":"OK",
"content_id":"vid0000001",
"session_key":"MTIzNDU2Nzg5MDEyMzQ1",
"drm":[
{
"type":"widevine",
"system_id":"edef8ba979d64acea3c827dcd51d21ed"
},


GoogleConfidential Page6of14
{
"type":"playready",
"system_id":"79f0049a40988642ab92e65be0885f95"
}
],
"tracks":[
{
pssh:[
{
drm_type:widevine,
"pssh_data":"aDM0aDM0MjNrMDAyODVubm5uZ2dnZzMyNDM0MmRmYWRm"
},
{
drm_type:playready,
pssh_data:TODO:AddXMLdata
}
]
"key_id":"MTIzNDU2Nzg5MDExMTExMQ==",
"type":"HD",
"key":"MTIzNDU2Nzg5MDAwMDAwMQ=="
},
{
pssh:[
{
drm_type:widevine,
"pssh_data":"aDM0aDM0MjNrMDAyODVtbW1tZ2dnZzMyNDM0MmRmYWRm"
},
{
drm_type:playready,
pssh_data:TODO:AddXMLdata
}
]
"key_id":"MTIzNDU2Nzg5MDIyMjIyMg==",
"type":"SD",
"key":"MTIzNDU4Nzg5MDAwMDAwMg==",
"iv":"MTIzNDU2Nzg5MDEyMzQ1"
},
{
pssh:[
{
drm_type:widevine,
"pssh_data":"aDM0aDM0MjNrMDAyODVtbW1tZ2dnZzMyNDM0MmRmYWRm"
},
{
drm_type:playready,
pssh_data:TODO:AddXMLdata
}
]

GoogleConfidential Page7of14
"key_id":"MTIzNDU2Nzg5MDMzMzMzMw==",
"type":"AUDIO",
"key":"MTIzNDU6Nzg5MDAwMDAwMg=="
}
]
}

Name Value Description

status string Ifsuccessful,OKisreturned.Otherwiseanerror


codeisreturnedtoindicatefailure.
SeeStatusCodes
tablebelow.

session_key Base64encodedbinarystring OptionalAES128bitrandomkeyusedtoencrypt


thecontentkeys.Thesession_keyisencrypted
withtheclientsRSAkeyspecifiedintherequest.

drm arrayofJSONstruct. AlistofDRMsystems.

drm.type String. TheDRMsystem.



oneof:
WIDEVINE
PLAYREADY

drm.system_id string RegisteredsystemIdfortheDRMsystem.

tracks.pssh arrayofJSONstruct AlistofPSSH,oneperDRMsystem.

tracks.pssh.drm_ string TheDRMsystemforaspecificpieceofPSSH


type

tracks.pssh.data Base64encodedstring PSSH(protectionsystemspecificheader)data.


ThePSSHdataisuniquepertrack.

tracks.key_id Base64encodedstring Uniqueidentifierforthekey.



Binary,16bytes

tracks.type Oneof: Identifiesthetracktypeencryptedwiththiskey.


HD Thesevaluesareextractedfromtherequest.
SD
AUDIO

tracks.key Base64encodedstring Contentkey.Ifthesession_keyisspecified,the


contentkeyisAESECBencryptedwiththe
Binary,16bytes sessionkey.Thesessionkeyisgeneratedbythe
DRMserverandencryptedwiththecontent
providerspublickeyusingRSAOAEP(sha1,
mgf1sha1).TheencryptedkeyisBase64encoded.


GoogleConfidential Page8of14
already_used Boolean Settotrueifthekey_idwaspreviouslyissued.
Thiscanhappenifapreviouskeyrequestfromthe
samesignerwiththesamecontent_idand
track_typewassent.

Signing the response


GeneratetheJSONstring.
Json::StyledWriterwriter
std::stringclear_message=writer.write(root)

Signthemessage.
RSAPSS

Status codes

Code Description

OK Success.

SIGNATURE_FAILED Theserverwasunabletoauthenticatethemessage.Perhaps:
Thespecified<signer>isunknown
The<signature>wasnotspecified,butisrequiredinthis
case.

CONTENT_ID_MISSING <content_id>fieldismissingintherequest.

POLICY_UNKNOWN Thespecified<policy>wasnotfoundforthis<signer>.

TRACK_TYPE_MISSING <tracks.type>ismissingintherequest.

TRACK_TYPE_UNKNOWN Thespecified<tracks.type>isnotoneoftheallowedvalues.

MALFORMED_REQUEST Therequestisnotformattedcorrectly.

ACCESS_DENIED


GoogleConfidential Page9of14

PSSH
BelowistheWidevinePSSHformatforcontentproviderswhowishtosynthesisthePSSH
ratherthanusingtheonesreturnedbytheAPI.Thestructurebelowisaprotocolbuffer(see
https://developers.google.com/protocolbuffers/
).Theprocessis:
1)Buildtheprotocolbuffermessagebelow.
2)Serializethemessagetobytes.
3)Base64encodethebytes.


message
WidevineCencHeader{

enum
Algorithm{
UNENCRYPTED=
0

AESCTR=
1

}

optional
Algorithmalgorithm=
1


repeated
byteskey_id=
2



//Contentprovidername.

optional

string
provider=
3



//Acontentidentifier,specifiedbycontentprovider.

optional
bytescontent_id=
4



//Tracktype.AcceptablevaluesareSD,HDandAUDIO.Usedto
//differentiate

contentkeysusedbyanasset.

optional

string
track_type_deprecated=
5



//Thenameofaregisteredpolicytobeusedforthisasset.

optional

string
policy=
6



//
Cryptoperiodindex,formediausingkeyrotation.

optionaluint32
crypto_period_index=
7


//Optionalprotectedcontextforgroupcontent.Thegrouped_licenseisa
//serializedSignedMessage.

optionalbytes
grouped_license=
8



//Protectionschemeidentifyingtheencryptionalgorithm.
//Representedasoneofthefollowing4CCvalues:
//'cenc'(AESCTR),'cbc1'(AESCBC),
//'cens'(AESCTRsubsample),'cbcs'(AESCBCsubsample).
optionaluint32
protection_scheme=
9



//Optional.Formediausingkeyrotation,thisrepresentstheduration
//ofeachcryptoperiodinseconds.
optionaluint32
crypto_period_seconds=
10

}


GoogleConfidential Page10of14
PSSH in the MPD

Incompliancewith
DASHIFInteroperabilityPoints
,WidevinesupportsinsertionofthePSSHin
theDASHMPDfile.

ThePSSHbox,includingitsheader,mustbebase64encodedandplacedinthe<cenc:pssh>
elementnestedunderthe<ContentProtection>element.Seetheexamplebelow:

<AdaptationSetmimeType="audio/mp4">
<ContentProtection
schemeIdUri=
urn:uuid:edef8ba979d64acea3c827dcd51d21ed
">
<cenc:pssh>AAAANHBzc2gAAAAA7e+</cenc:pssh>
</ContentProtection>


GoogleConfidential Page11of14
Test Player
Tohelpintegrationandverification,thefollowingcanbeusedtoplaybackWidevineCENC
content:

Demo URLs for players


http://shakaplayerdemo.appspot.com/

Content URL
http://storage.googleapis.com/wvmedia/cenc/tears.mpd

WidevinehaspublishedanopensourceHTML5DASHplayer,availableat:

githubsite:
https://github.com/google/shakaplayer
changelog: https://github.com/google/shakaplayer/blob/master/CHANGELOG.md
hosteddemo: http://shakaplayerdemo.appspot.com/
hostedcopyofdocumentation: http://shakaplayerdemo.appspot.com/docs/index.html
hostedcopyofthefinaltutorialfromthedocs:
http://turtletube.appspot.com/


GoogleConfidential Page12of14
Appendix
Sample Request
Provider:widevine_test
ContentID:fkj3ljaSdfalkr3j
Policy:emptystring

Hereisthecommandtoobtainkeysforthissampleasset:

wgetO/tmp/keypostdata'{"request":
"ewogICJjb250ZW50X2lkIjogIlptdHFNMnhxWVZOa1ptRnNhM0l6YWc9PSIsCiAgInRyYWNrcyI6I
FsKICAgIHsgInR5cGUiOiAiU0QiIH0sCiAgICB7ICJ0eXBlIjogIkhEIiB9LAogICAgeyAidHlwZSI
6ICJBVURJTyIgfQogIF0sCiAgImRybV90eXBlcyI6IFsgIldJREVWSU5FIiBdLAogICJwb2xpY3kiO
iAiIgp9Cg==","signature":"kwVLL4xVh9mnlZlPqiEWN0E+FsvG0y+/oy451XXeIMo=",
"signer":"widevine_test"}'
http://license.uat.widevine.com/cenc/getcontentkey/widevine_test

Theexpectedresponseshouldbe:

{"response":"eyJzdGF0dXMiOiJPSyIsImRybSI6W3sidHlwZSI6IldJREVWSU5FIiwic3lzdGVtX
2lkIjoiZWRlZjhiYTk3OWQ2NGFjZWEzYzgyN2RjZDUxZDIxZWQifV0sInR
yYWNrcyI6W3sidHlwZSI6IlNEIiwia2V5X2lkIjoiQXBTNVdaMTFYZUs3OFAzS1A2WHF0dz09Iiwia
2V5IjoiTzlvdlFEUk1mZTloUWllNXdQQStKZz09IiwicHNzaCI6W3siZHJ
tX3R5cGUiOiJXSURFVklORSIsImRhdGEiOiJDQUVTRUFLVXVWbWRkVjNpdS9EOXlqK2w2cmNhRFhkc
FpHVjJhVzVsWDNSbGMzUWlFR1pyYWpOc2FtRlRaR1poYkd0eU0yb3FBbE5
FTWdBPSJ9XX0seyJ0eXBlIjoiSEQiLCJrZXlfaWQiOiI2MmRxdThzMFhwYTd6MkZtTVBHajJnPT0iL
CJrZXkiOiJFQXRzSUpRUGQ1cEZpUlVyVjlMYXl3PT0iLCJwc3NoIjpbeyJ
kcm1fdHlwZSI6IldJREVWSU5FIiwiZGF0YSI6IkNBRVNFT3RuYXJ2TE5GNld1ODloWmpEeG85b2FEW
GRwWkdWMmFXNWxYM1JsYzNRaUVHWnJhak5zYW1GVFpHWmhiR3R5TTJvcUF
raEVNZ0E9In1dfSx7InR5cGUiOiJBVURJTyIsImtleV9pZCI6Ilk1Mm9EUEk3VmZPNHlyUDJUUHBkO
Wc9PSIsImtleSI6IklwOWZLYlpENGdNQVN6REU2dk5JOUE9PSIsInBzc2g
iOlt7ImRybV90eXBlIjoiV0lERVZJTkUiLCJkYXRhIjoiQ0FFU0VHT2RxQXp5TzFYenVNcXo5a3o2W
GZZYURYZHBaR1YyYVc1bFgzUmxjM1FpRUdacmFqTnNhbUZUWkdaaGJHdHl
NMm9xQlVGVlJFbFBNZ0E9In1dfV0sImFscmVhZHlfdXNlZCI6dHJ1ZX0="}

Decodetheresponse
cutd:f2/tmp/key|base64di

{"status":"OK","drm":[{"type":"WIDEVINE","system_id":"edef8ba979d64acea3c827dc
d51d21ed"}],"tracks":[{"type":"SD","key_id":"ApS5WZ11XeK78P3KP6Xqtw==","key":"
O9ovQDRMfe9hQie5wPA+Jg==","pssh":[{"drm_type":"WIDEVINE","data":"CAESEAKUuVmdd
V3iu/D9yj+l6rcaDXdpZGV2aW5lX3Rlc3QiEGZrajNsamFTZGZhbGtyM2oqAlNEMgA="}]},{"type
":"HD","key_id":"62dqu8s0Xpa7z2FmMPGj2g==","key":"EAtsIJQPd5pFiRUrV9Layw==","p
ssh":[{"drm_type":"WIDEVINE","data":"CAESEOtnarvLNF6Wu89hZjDxo9oaDXdpZGV2aW5lX
3Rlc3QiEGZrajNsamFTZGZhbGtyM2oqAkhEMgA="}]},{"type":"AUDIO","key_id":"Y52oDPI7
VfO4yrP2TPpd9g==","key":"Ip9fKbZD4gMASzDE6vNI9A==","pssh":[{"drm_type":"WIDEVI

GoogleConfidential Page13of14
NE","data":"CAESEGOdqAzyO1XzuMqz9kz6XfYaDXdpZGV2aW5lX3Rlc3QiEGZrajNsamFTZGZhbG
tyM2oqBUFVRElPMgA="}]}],"already_used":true}

Signing
Thesignatureisgeneratedasfollows.
1. Taketherawvalueoftherequestfield(notinbase64encoding).
{"policy":"test_policy","tracks":[{"type":"SD"},{"type":"HD"},
{"type":"AUDIO"}],"content_id":"dGVzdF9pZF9GOUZQQzBOTw=="}

2. ComputeitsSHA1hash(thisexampleuseswidevine_testkeys).
306814a9_12abd779_de5dd373_89ca45d9_7328e89c

3. EncryptthehashwithAESCBC.Theresultisthesignature:
46f1ee6e3660acb081106c78e45e190464d87e5f8f7c79143c34da0308ec4bfc

4. Base64encodethesignature:
RvHubjZgrLCBEGx45F4ZBGTYfl+PfHkUPDTaAwjsS/w=

5. Addsignaturetotherequest:
{"request":
"eyJwb2xpY3kiOiAidGVzdF9wb2xpY3kiLCAidHJhY2tzIjogW3sidHlwZSI6ICJTRCJ9LCB
7InR5cGUiOiAiSEQifSwgeyJ0eXBlIjogIkFVRElPIn1dLCAiY29udGVudF9pZCI6ICJkR1Z
6ZEY5cFpGOUdPVVpRUXpCT1R3PT0ifQ==",
"signer":"widevine_test",
"signature":"RvHubjZgrLCBEGx45F4ZBGTYfl+PfHkUPDTaAwjsS/w="}

Forintegrationtests,youcanusewidevine_testasthesigner.ItsAESkeyis
0x1a,0xe8,0xcc,0xd0,0xe7,0x98,0x5c,0xc0,
0xb6,0x20,0x3a,0x55,0x85,0x5a,0x10,0x34,
0xaf,0xc2,0x52,0x98,0x0e,0x97,0x0c,0xa9,
0x0e,0x52,0x02,0x68,0x9f,0x94,0x7a,0xb9
TheIVis
0xd5,0x8c,0xe9,0x54,0x20,0x3b,0x7c,0x9a,
0x9a,0x9d,0x46,0x7f,0x59,0x83,0x92,0x49


GoogleConfidential Page14of14

Vous aimerez peut-être aussi