使用媒体服务传送 DRM 许可证或 AES 密钥Use Media Services to deliver DRM licenses or AES keys

备注

Google Widevine 目前在中国地区不可用。Google Widevine is not avaliable in China regions now.

备注

若要完成本教程,需要一个 Azure 帐户。To complete this tutorial, you need an Azure account. 有关详细信息,请参阅 Azure 1 元试用For details, see Azure 1rmb Trial. 不会向媒体服务 v2 添加任何新特性或新功能。No new features or functionality are being added to Media Services v2.
查看最新版本:媒体服务 v3Check out the latest version, Media Services v3. 另请参阅从 v2 到 v3 的迁移指南Also, see migration guidance from v2 to v3

Azure 媒体服务可引入、编码、添加内容保护,以及流式传输内容。Azure Media Services enables you to ingest, encode, add content protection, and stream your content. 有关详细信息,请参阅使用 PlayReady 动态通用加密For more information, see Use PlayReady dynamic common encryption. 一些客户希望将媒体服务仅用于传送许可证和/或密钥,以及通过使用其本地服务器进行编码、加密和流式处理。Some customers want to use Media Services only to deliver licenses and/or keys and encode, encrypt, and stream by using their on-premises servers. 本文说明如何使用媒体服务来传送 PlayReady 许可证,但使用本地服务器来完成其余部分。This article describes how you can use Media Services to deliver PlayReady license but do the rest with your on-premises servers.

概述Overview

媒体服务提供传送 PlayReady 数字版权管理 (DRM) 许可证及 AES-128 密钥的服务。Media Services provides a service for delivering PlayReady digital rights management (DRM) license and AES-128 keys. 媒体服务还提供用于配置所需权限和限制的 API,这样当用户播放 DRM 保护的内容时,DRM 运行时便会强制实施这些权限和限制。Media Services also provides APIs that let you configure the rights and restrictions that you want for the DRM runtime to enforce when a user plays back the DRM-protected content. 当用户请求受保护的内容时,播放器应用程序会从媒体服务许可证服务请求许可证。When a user requests the protected content, the player application requests a license from the Media Services license service. 如果许可证获得授权,媒体服务许可证服务会向该播放器颁发许可证。If the license is authorized, the Media Services license service issues the license to the player. PlayReady 许可证包含客户端播放器用来对内容进行解密和流式传输的解密密钥。The PlayReady licenses contain the decryption key that can be used by the client player to decrypt and stream the content.

媒体服务支持通过多种方式对发出许可证或密钥请求的用户进行授权。Media Services supports multiple ways of authorizing users who make license or key requests. 配置内容密钥授权策略。You configure the content key's authorization policy. 策略可以有一个或多个限制。The policy can have one or more restrictions. 选项为打开或令牌限制。The options are open or token restriction. 令牌限制策略必须附带由安全令牌服务 (STS) 颁发的令牌。The token-restricted policy must be accompanied by a token issued by a security token service (STS). 媒体服务支持采用简单 Web 令牌 (SWT) 格式和 JSON Web 令牌 (JWT) 格式的令牌。Media Services supports tokens in the simple web token (SWT) format and the JSON Web Token (JWT) format.

下图显示了使用媒体服务传送 PlayReady 许可证,但使用本地服务器完成其余部分所要执行的主要步骤:The following diagram shows the main steps you need to take to use Media Services to deliver PlayReady license but do the rest with your on-premises servers:

使用 PlayReady 进行保护

下载示例Download sample

若要下载本文中所述的示例,请参阅在 .NET 中使用 Azure 媒体服务传送 PlayReady 许可证To download the sample described in this article, see Use Azure Media Services to deliver PlayReady license with .NET.

创建和配置 Visual Studio 项目Create and configure a Visual Studio project

  1. 设置开发环境,并根据使用 .NET 进行媒体服务开发中所述,在 app.config 文件中填充连接信息。Set up your development environment, and populate the app.config file with connection information, as described in Media Services development with .NET.

  2. 将以下元素添加到 app.config 文件中定义的 appSettings:Add the following elements to appSettings defined in your app.config file:

    <add key="Issuer" value="http://testissuer.com"/>
    <add key="Audience" value="urn:test"/>
    

.NET 代码示例.NET code example

以下代码示例演示如何创建通用内容密钥,并获取 PlayReady 许可证获取 URL。The following code example shows how to create a common content key and get PlayReady license acquisition URLs. 若要配置本地服务器,需要一个内容密钥、密钥 ID 和许可证获取 URL。To configure your on-premises server, you need a content key, the key ID, and the license acquisition URL. 配置本地服务器后,可以从自己的流服务器进行流式传输。After you configure your on-premises server, you can stream from your own streaming server. 由于加密的流指向媒体服务许可证服务器,因此播放器会从媒体服务请求许可证。Because the encrypted stream points to a Media Services license server, your player requests a license from Media Services. 如果选择令牌身份验证,则媒体服务许可证服务器将对通过 HTTPS 发送的令牌进行验证。If you choose token authentication, the Media Services license server validates the token you sent through HTTPS. 如果该令牌有效,许可证服务器会将许可证传递回播放器中。If the token is valid, the license server delivers the license back to your player. 以下代码示例仅演示如何创建通用内容密钥,并获取 PlayReady 许可证获取 URL。The following code example only shows how to create a common content key and get PlayReady license acquisition URL. 如果想要传送 AES-128 密钥,则需要创建信封内容密钥,并获取密钥获取 URL。If you want to deliver AES-128 keys, you need to create an envelope content key and get a key acquisition URL. 有关详细信息,请参阅使用 AES-128 动态加密和密钥传递服务For more information, see Use AES-128 dynamic encryption and key delivery service.

using System;
using System.Collections.Generic;
using System.Configuration;
using Microsoft.WindowsAzure.MediaServices.Client;
using Microsoft.WindowsAzure.MediaServices.Client.ContentKeyAuthorization;
using Newtonsoft.Json;

namespace DeliverDRMLicenses
{
    class Program
    {
        // Read values from the App.config file.
        private static readonly string _AADTenantDomain =
            ConfigurationManager.AppSettings["AMSAADTenantDomain"];
        private static readonly string _RESTAPIEndpoint =
            ConfigurationManager.AppSettings["AMSRESTAPIEndpoint"];
        private static readonly string _AMSClientId =
            ConfigurationManager.AppSettings["AMSClientId"];
        private static readonly string _AMSClientSecret =
            ConfigurationManager.AppSettings["AMSClientSecret"];

        private static readonly Uri _sampleIssuer =
            new Uri(ConfigurationManager.AppSettings["Issuer"]);
        private static readonly Uri _sampleAudience =
            new Uri(ConfigurationManager.AppSettings["Audience"]);

        // Field for service context.
        private static CloudMediaContext _context = null;

        static void Main(string[] args)
        {
            AzureAdTokenCredentials tokenCredentials =
                new AzureAdTokenCredentials(_AADTenantDomain,
                    new AzureAdClientSymmetricKey(_AMSClientId, _AMSClientSecret),
                    AzureEnvironments.AzureChinaCloudEnvironment);

            var tokenProvider = new AzureAdTokenProvider(tokenCredentials);

            _context = new CloudMediaContext(new Uri(_RESTAPIEndpoint), tokenProvider);

            bool tokenRestriction = true;
            string tokenTemplateString = null;


            IContentKey key = CreateCommonTypeContentKey();

            // Print out the key ID and Key in base64 string format
            Console.WriteLine("Created key {0} with key value {1} ",
                key.Id, System.Convert.ToBase64String(key.GetClearKeyValue()));

            Console.WriteLine("PlayReady License Key delivery URL: {0}",
                key.GetKeyDeliveryUrl(ContentKeyDeliveryType.PlayReadyLicense));

         

            if (tokenRestriction)
                tokenTemplateString = AddTokenRestrictedAuthorizationPolicy(key);
            else
                AddOpenAuthorizationPolicy(key);

            Console.WriteLine("Added authorization policy: {0}",
                key.AuthorizationPolicyId);
            Console.WriteLine();
            Console.ReadLine();
        }

        static public void AddOpenAuthorizationPolicy(IContentKey contentKey)
        {

            // Create ContentKeyAuthorizationPolicy with Open restrictions 
            // and create authorization policy          

            List<ContentKeyAuthorizationPolicyRestriction> restrictions =
                new List<ContentKeyAuthorizationPolicyRestriction>
            {
                        new ContentKeyAuthorizationPolicyRestriction
                        {
                            Name = "Open",
                            KeyRestrictionType = (int)ContentKeyRestrictionType.Open,
                            Requirements = null
                        }
            };

            // Configure PlayReady  license templates.
            string PlayReadyLicenseTemplate = ConfigurePlayReadyLicenseTemplate();


            IContentKeyAuthorizationPolicyOption PlayReadyPolicy =
                _context.ContentKeyAuthorizationPolicyOptions.Create("",
                    ContentKeyDeliveryType.PlayReadyLicense,
                        restrictions, PlayReadyLicenseTemplate);

           

            IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                        ContentKeyAuthorizationPolicies.
                        CreateAsync("Deliver Common Content Key with no restrictions").
                        Result;


            contentKeyAuthorizationPolicy.Options.Add(PlayReadyPolicy);
            
            // Associate the content key authorization policy with the content key.
            contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
            contentKey = contentKey.UpdateAsync().Result;
        }

        public static string AddTokenRestrictedAuthorizationPolicy(IContentKey contentKey)
        {
            string tokenTemplateString = GenerateTokenRequirements();

            List<ContentKeyAuthorizationPolicyRestriction> restrictions =
                new List<ContentKeyAuthorizationPolicyRestriction>
            {
                        new ContentKeyAuthorizationPolicyRestriction
                        {
                            Name = "Token Authorization Policy",
                            KeyRestrictionType = (int)ContentKeyRestrictionType.TokenRestricted,
                            Requirements = tokenTemplateString,
                        }
            };

            // Configure PlayReady  license templates.
            string PlayReadyLicenseTemplate = ConfigurePlayReadyLicenseTemplate();


            IContentKeyAuthorizationPolicyOption PlayReadyPolicy =
                _context.ContentKeyAuthorizationPolicyOptions.Create("Token option",
                    ContentKeyDeliveryType.PlayReadyLicense,
                        restrictions, PlayReadyLicenseTemplate);

        

            IContentKeyAuthorizationPolicy contentKeyAuthorizationPolicy = _context.
                        ContentKeyAuthorizationPolicies.
                        CreateAsync("Deliver Common Content Key with token restrictions").
                        Result;

            contentKeyAuthorizationPolicy.Options.Add(PlayReadyPolicy);
          

            // Associate the content key authorization policy with the content key
            contentKey.AuthorizationPolicyId = contentKeyAuthorizationPolicy.Id;
            contentKey = contentKey.UpdateAsync().Result;

            return tokenTemplateString;
        }

        static private string GenerateTokenRequirements()
        {
            TokenRestrictionTemplate template = new TokenRestrictionTemplate(TokenType.SWT);

            template.PrimaryVerificationKey = new SymmetricVerificationKey();
            template.AlternateVerificationKeys.Add(new SymmetricVerificationKey());
            template.Audience = _sampleAudience.ToString();
            template.Issuer = _sampleIssuer.ToString();
            template.RequiredClaims.Add(TokenClaim.ContentKeyIdentifierClaim);

            return TokenRestrictionTemplateSerializer.Serialize(template);
        }

        static private string ConfigurePlayReadyLicenseTemplate()
        {
            // The following code configures PlayReady License Template using .NET classes
            // and returns the XML string.

            //The PlayReadyLicenseResponseTemplate class represents the template 
            //for the response sent back to the end user. 
            //It contains a field for a custom data string between the license server 
            //and the application (may be useful for custom app logic) 
            //as well as a list of one or more license templates.

            PlayReadyLicenseResponseTemplate responseTemplate =
                new PlayReadyLicenseResponseTemplate();

            // The PlayReadyLicenseTemplate class represents a license template 
            // for creating PlayReady licenses
            // to be returned to the end users. 
            // It contains the data on the content key in the license 
            // and any rights or restrictions to be 
            // enforced by the PlayReady DRM runtime when using the content key.
            PlayReadyLicenseTemplate licenseTemplate = new PlayReadyLicenseTemplate();

            // Configure whether the license is persistent 
            // (saved in persistent storage on the client) 
            // or non-persistent (only held in memory while the player is using the license).  
            licenseTemplate.LicenseType = PlayReadyLicenseType.Nonpersistent;

            // AllowTestDevices controls whether test devices can use the license or not.  
            // If true, the MinimumSecurityLevel property of the license
            // is set to 150.  If false (the default), 
            // the MinimumSecurityLevel property of the license is set to 2000.
            licenseTemplate.AllowTestDevices = true;

            // You can also configure the Play Right in the PlayReady license by using the PlayReadyPlayRight class. 
            // It grants the user the ability to play back the content subject to the zero or more restrictions 
            // configured in the license and on the PlayRight itself (for playback specific policy). 
            // Much of the policy on the PlayRight has to do with output restrictions 
            // which control the types of outputs that the content can be played over and 
            // any restrictions that must be put in place when using a given output.
            // For example, if the DigitalVideoOnlyContentRestriction is enabled, 
            //then the DRM runtime will only allow the video to be displayed over digital outputs 
            //(analog video outputs won’t be allowed to pass the content).

            // IMPORTANT: These types of restrictions can be very powerful 
            // but can also affect the consumer experience. 
            // If the output protections are configured too restrictive, 
            // the content might be unplayable on some clients. 
            // For more information, see the PlayReady Compliance Rules document.

            // For example:
            //licenseTemplate.PlayRight.AgcAndColorStripeRestriction = new AgcAndColorStripeRestriction(1);

            responseTemplate.LicenseTemplates.Add(licenseTemplate);

            return MediaServicesLicenseTemplateSerializer.Serialize(responseTemplate);
        }




        static public IContentKey CreateCommonTypeContentKey()
        {
            // Create envelope encryption content key
            Guid keyId = Guid.NewGuid();
            byte[] contentKey = GetRandomBuffer(16);

            IContentKey key = _context.ContentKeys.Create(
                                    keyId,
                                    contentKey,
                                    "ContentKey",
                                    ContentKeyType.CommonEncryption);

            return key;
        }

        static private byte[] GetRandomBuffer(int length)
        {
            var returnValue = new byte[length];

            using (var rng =
                new System.Security.Cryptography.RNGCryptoServiceProvider())
            {
                rng.GetBytes(returnValue);
            }

            return returnValue;
        }
    }
}

媒体服务学习路径Media Services learning paths

媒体服务 v3(最新版本)Media Services v3 (latest)

查看最新版本的 Azure 媒体服务!Check out the latest version of Azure Media Services!

媒体服务 v2(旧版)Media Services v2 (legacy)

另请参阅See also