edit-icon download-icon

HLS encryption and play

Last Updated: May 04, 2018

Purpose

This document describes the complete procedure of creating HLS standard encryption workflow to play the encrypted video.

For more information about the architecture of HLS standard encryption, see HLS standard encryption.

Procedure

1. Create HLS encryption workflow.

For more information about creating HLS encryption workflow and DEMO code, see Create HLS standard encryption workflow.

Note: When creating HLS standard workfow, enter http: //127.0.0.1:8888 in the value of the HLS_KEY_URI parameter for a test. When playing, the player request the key to this address, and we create a service to distribute key.

2. Upload and encrypt video.

Upload a video by using Media Files in the MPS console. When selecting workflow, select the newly created HLS standard encryption workflow. After uploading, the workflow automatically triggers encryption transcoding. When the video is in the published status, follow these steps.

3. Create local authentication service.

Create a local HTTP service, which serves as authentication service in playing HLS standard encryption video, to issue and verify MtsHlsUriToken token.

Java code dependency example:

https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-core

https://mvnrepository.com/artifact/com.aliyun/aliyun-java-sdk-kms

  1. package com.aliyun.smallcode;
  2. import com.aliyuncs.DefaultAcsClient;
  3. import com.aliyuncs.exceptions.ClientException;
  4. import com.aliyuncs.http.ProtocolType;
  5. import com.aliyuncs.kms.model.v20160120.DecryptRequest;
  6. import com.aliyuncs.kms.model.v20160120.DecryptResponse;
  7. import com.aliyuncs.profile.DefaultProfile;
  8. import com.sun.net.httpserver.Headers;
  9. import com.sun.net.httpserver.HttpExchange;
  10. import com.sun.net.httpserver.HttpHandler;
  11. import com.sun.net.httpserver.HttpServer;
  12. import com.sun.net.httpserver.spi.HttpServerProvider;
  13. import org.apache.commons.codec.binary.Base64;
  14. import java.io.IOException;
  15. import java.io.OutputStream;
  16. import java.net.HttpURLConnection;
  17. import java.net.InetSocketAddress;
  18. import java.net.URI;
  19. import java.util.regex.Matcher;
  20. import java.util.regex.Pattern;
  21. public class AuthorizationServer {
  22. private static DefaultAcsClient client;
  23. static {
  24. String region = "<your-region-id>";
  25. String accessKeyId = "<your-access-key-id>";
  26. String accessKeySecret = "<your-access-key-secret>";
  27. client = new DefaultAcsClient(DefaultProfile.getProfile(region, accessKeyId, accessKeySecret));
  28. }
  29. public class AuthorizationHandler implements HttpHandler {
  30. public void handle(HttpExchange httpExchange) throws IOException {
  31. String requestMethod = httpExchange.getRequestMethod();
  32. if(requestMethod.equalsIgnoreCase("GET")){
  33. //Get ciphertext and key from URL
  34. String ciphertext = getCiphertext(httpExchange);
  35. if (null == ciphertext)
  36. return;
  37. //decrypt ciphertext from KMS, and Base64 decode
  38. byte[] key = decrypt(ciphertext);
  39. //Set header
  40. setHeader(httpExchange, key);
  41. //Response key
  42. OutputStream responseBody = httpExchange.getResponseBody();
  43. responseBody.write(key);
  44. responseBody.close();
  45. }
  46. }
  47. private void setHeader(HttpExchange httpExchange, byte[] key) throws IOException {
  48. Headers responseHeaders = httpExchange.getResponseHeaders();
  49. responseHeaders.set("Access-Control-Allow-Origin", "*");
  50. httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, key.length);
  51. }
  52. private byte[] decrypt(String ciphertext) {
  53. DecryptRequest request = new DecryptRequest();
  54. request.setCiphertextBlob(ciphertext);
  55. request.setProtocol(ProtocolType.HTTPS);
  56. try {
  57. DecryptResponse response = client.getAcsResponse(request);
  58. String plaintext = response.getPlaintext();
  59. //Note: require base64 decode
  60. return Base64.decodeBase64(plaintext);
  61. } catch (ClientException e) {
  62. e.printStackTrace();
  63. return null;
  64. }
  65. }
  66. private String getCiphertext(HttpExchange httpExchange) {
  67. URI uri = httpExchange.getRequestURI();
  68. String queryString = uri.getQuery();
  69. String pattern = "Ciphertext=(\\w*)";
  70. Pattern r = Pattern.compile(pattern);
  71. Matcher m = r.matcher(queryString);
  72. if (m.find())
  73. return m.group(1);
  74. else {
  75. System.out.println("Not Found Ciphertext");
  76. return null;
  77. }
  78. }
  79. }
  80. private void startService() throws IOException {
  81. HttpServerProvider provider = HttpServerProvider.provider();
  82. //listening port 8888 can accept 10 request simultaneously
  83. HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8888), 10);
  84. httpserver.createContext("/", new AuthorizationHandler());
  85. httpserver.start();
  86. System.out.println("server started");
  87. }
  88. public static void main(String[] args) throws IOException {
  89. AuthorizationServer server = new AuthorizationServer();
  90. server.startService();
  91. }
  92. }

Python code dependency example:

pip install aliyun-python-sdk-core

pip install aliyun-python-sdk-kms

pip install aliyun-python-sdk-mts

  1. # -*- coding: UTF-8 -*-
  2. from BaseHTTPServer import BaseHTTPRequestHandler
  3. from aliyunsdkcore.client import AcsClient
  4. from aliyunsdkkms.request.v20160120 import DecryptRequest
  5. import cgi
  6. import json
  7. import base64
  8. import urlparse
  9. client = AcsClient("<your-access-key-id>","<your-access-key-secret>","<your-region-id>");
  10. class AuthorizationHandler(BaseHTTPRequestHandler):
  11. def do_GET(self):
  12. self.check()
  13. self.set_header()
  14. cipertext = self.get_cihpertext()
  15. plaintext = self.decrypt_cihpertext(cipertext)
  16. print plaintext
  17. key = base64.b64decode(plaintext)
  18. print key
  19. self.wfile.write(key)
  20. def do_POST(self):
  21. pass
  22. def check(self):
  23. #check MtsHlsUriToken, etc.
  24. pass
  25. def set_header(self):
  26. self.send_response(200)
  27. #cors
  28. self.send_header('Access-Control-Allow-Origin', '*')
  29. self.end_headers()
  30. def get_cihpertext(self):
  31. path = urlparse.urlparse(self.path)
  32. query = urlparse.parse_qs(path.query)
  33. return query.get('Ciphertext')[0]
  34. def decrypt_cihpertext(self, cipertext):
  35. request = DecryptRequest.DecryptRequest()
  36. request.set_CiphertextBlob(cipertext)
  37. response = client.do_action_with_exception(request)
  38. jsonResp = json.loads(response)
  39. return jsonResp["Plaintext"]
  40. if __name__ == '__main__':
  41. # Start a simple server, and loop forever
  42. from BaseHTTPServer import HTTPServer
  43. print "Starting server, use <Ctrl-C> to stop"
  44. server = HTTPServer(('127.0.0.1', 8888), AuthorizationHandler)
  45. server.serve_forever()

4. Obtain playback address.

You can obtain playback address by multiple ways. For more information, see Questions about MPS file output.

5. Play video.

By using an online player, test the playback of HLS encryption video. For more information, see Alibaba Cloud player user diagnositc tool.

Enter the playback address obtained from step 4 to the dialogue box as shown in the following figure, and click “play**.

Note: By using browser DEBUG, the player automatically request authentication server, obtain decryption key and do the playback operation after decryption.

2

Thank you! We've received your feedback.