阿里云视频加密

阿里云视频加密(又称阿里云私有加密)可针对直播流进行加密,本文介绍优势、整体架构和使用方法。

说明
  • 仅支持输出HLS格式和FLV格式。

  • 只能使用阿里云播放器。

  • H5端支持情况参见浏览器适配说明阿里云私有加密视频播放功能项。

背景

防盗链URL不能防止用户通过一次付费行为拿到付费直播合法的防盗链URL,进而实现二次分发。因此,防盗链方案对于直播的版权保护是远远不够的。

优势介绍

阿里云视频加密是对视频数据加密,即使下载到本地,视频本身也是被加密的,无法恶意二次分发。视频加密可有效防止视频泄露和盗链问题,广泛用于在线教育、财经金融、行业培训、独播剧等在线版权视频领域。

采用阿里云私有加密算法,安全级别高,能够便捷、高效、安全地保护视频资源。

  • 每个媒体文件拥有独立的加密钥匙,能有效避免采用单一密钥时,一个密钥的泄露引起大范围的安全问题。

  • 视频直播提供完善的权限管理机制“子账号+播放凭证”。

  • 视频直播提供信封加密机制”密文Key+明文Key”,明文Key不存储,所有过程只在内存中。

  • 视频直播提供安全的播放内核SDK。

整体架构

阿里云视频加密方案包含两部分:加密转码+解密播放。

  • 加密转码:流程1~3。

    主播推流到直播中心后,直播服务负责通过密钥管理服务KMS生成明文Key和密文Key。通过直播转码服务,使用明文密钥对音视频进行对称加密,并将密文Key存入视频封装。

  • 解密播放:流程4~11。

    播放终端如需播放此直播流,需向应用服务器AppServer发起播放请求,获取播流URL。使用播流URL向直播服务请求视频流。直播服务将经过转码的加密视频和密文Key传输到播放器SDK。

    播放终端用密文Key向直播服务获取二次加密后的明文Key,直播服务再通过密文Key向密钥管理服务KMS获取明文Key。播放终端将解密得到的明文Key传给播放器SDK,播放器SDK解密视频进行播放。

image

使用方式

阿里云视频加密是通过转码模板进行配置,可支持控制台和API两种配置方式。

重要

使用阿里云视频加密需要配置KMS密钥ID,如果没有密钥,请先前往KMS服务创建一个密钥,需注意创建密钥时KMS密钥的区域需要和域名的直播中心保持一致。具体操作,请参见创建密钥

方式一:通过视频直播控制台。具体操作,请参见通用转码自定义转码

方式二:API调用。

  1. 配置视频加密转码模板,可调用AddLiveStreamTranscode添加通用转码配置信息或调用AddCustomLiveStreamTranscode添加自定义转码配置信息,设置加密配置参数EncryptParameters,其中EncryptType加密类型取值aliyun

    Java SDK添加通用转码配置代码示例如下:

    // This file is auto-generated, don't edit it. Thanks.
    package demo;
    
    import com.aliyun.auth.credentials.Credential;
    import com.aliyun.auth.credentials.provider.StaticCredentialProvider;
    import com.aliyun.core.http.HttpClient;
    import com.aliyun.core.http.HttpMethod;
    import com.aliyun.core.http.ProxyOptions;
    import com.aliyun.httpcomponent.httpclient.ApacheAsyncHttpClientBuilder;
    import com.aliyun.sdk.service.live20161101.models.*;
    import com.aliyun.sdk.service.live20161101.*;
    import com.google.gson.Gson;
    import darabonba.core.RequestConfiguration;
    import darabonba.core.client.ClientOverrideConfiguration;
    import darabonba.core.utils.CommonUtil;
    import darabonba.core.TeaPair;
    
    //import javax.net.ssl.KeyManager;
    //import javax.net.ssl.X509TrustManager;
    import java.net.InetSocketAddress;
    import java.time.Duration;
    import java.util.*;
    import java.util.concurrent.CompletableFuture;
    import java.io.*;
    
    public class AddLiveStreamTranscode {
        public static void main(String[] args) throws Exception {
    
            // HttpClient Configuration
            /*HttpClient httpClient = new ApacheAsyncHttpClientBuilder()
                    .connectionTimeout(Duration.ofSeconds(10)) // Set the connection timeout time, the default is 10 seconds
                    .responseTimeout(Duration.ofSeconds(10)) // Set the response timeout time, the default is 20 seconds
                    .maxConnections(128) // Set the connection pool size
                    .maxIdleTimeOut(Duration.ofSeconds(50)) // Set the connection pool timeout, the default is 30 seconds
                    // Configure the proxy
                    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("<YOUR-PROXY-HOSTNAME>", 9001))
                            .setCredentials("<YOUR-PROXY-USERNAME>", "<YOUR-PROXY-PASSWORD>"))
                    // If it is an https connection, you need to configure the certificate, or ignore the certificate(.ignoreSSL(true))
                    .x509TrustManagers(new X509TrustManager[]{})
                    .keyManagers(new KeyManager[]{})
                    .ignoreSSL(false)
                    .build();*/
    
            // Configure Credentials authentication information, including ak, secret, token
            StaticCredentialProvider provider = StaticCredentialProvider.create(Credential.builder()
                    // Please ensure that the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are set.
                    .accessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
                    .accessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
                    //.securityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN")) // use STS token
                    .build());
    
            // Configure the Client
            AsyncClient client = AsyncClient.builder()
                    .region("<Your RegionId>") // Region ID
                    //.httpClient(httpClient) // Use the configured HttpClient, otherwise use the default HttpClient (Apache HttpClient)
                    .credentialsProvider(provider)
                    //.serviceConfiguration(Configuration.create()) // Service-level configuration
                    // Client-level configuration rewrite, can set Endpoint, Http request parameters, etc.
                    .overrideConfiguration(
                            ClientOverrideConfiguration.create()
                                      // Endpoint 请参考 https://api.aliyun.com/product/live
                                    .setEndpointOverride("live.aliyuncs.com")
                            //.setConnectTimeout(Duration.ofSeconds(30))
                    )
                    .build();
    
            // Parameter settings for API request
            AddLiveStreamTranscodeRequest addLiveStreamTranscodeRequest = AddLiveStreamTranscodeRequest.builder()
                    .regionId("<Your RegionId>")
                    .domain("<Your Domain>")
                    .app("<Your App Name>")
                    .template("<Your Template>")
                    .encryptParameters("<Your EncryptParameters>")
                    // Request-level configuration rewrite, can set Http request parameters, etc.
                    // .requestConfiguration(RequestConfiguration.create().setHttpHeaders(new HttpHeaders()))
                    .build();
    
            // Asynchronously get the return value of the API request
            CompletableFuture<AddLiveStreamTranscodeResponse> response = client.addLiveStreamTranscode(addLiveStreamTranscodeRequest);
            // Synchronously get the return value of the API request
            AddLiveStreamTranscodeResponse resp = response.get();
            System.out.println(new Gson().toJson(resp));
            // Asynchronous processing of return values
            /*response.thenAccept(resp -> {
                System.out.println(new Gson().toJson(resp));
            }).exceptionally(throwable -> { // Handling exceptions
                System.out.println(throwable.getMessage());
                return null;
            });*/
    
            // Finally, close the client
            client.close();
        }
    
    }
    说明
    • 如果更改转码配置,需要进行重新推流后配置才可生效。

    • 使用JAVA SDK,具体请参见Java SDK使用说明

  2. 其他相关API。

    API名称

    说明

    更新通用转码配置

    调用UpdateLiveStreamTranscode更新通用转码配置信息。

    更新自定义转码配置

    调用UpdateCustomLiveStreamTranscode更新自定义转码配置信息。

    查询直播流转码配置

    调用DescribeLiveStreamTranscodeInfo查询转码配置信息。

    删除转码配置

    调用DeleteLiveStreamTranscode删除转码配置信息。

相关文档

使用视频加密,会自动创建AliyunServiceRoleForLiveKes角色获取KMS服务访问权限,更多信息请参见直播加密服务关联角色