The following sample code in Java is for reference only. You can develop logic for decryption and MtsHlsUriToken verification based on your business requirements. The following table describes the parameters in the sample code that you can change based on your business requirements.
Parameter | Description |
region
| The region ID. KMS and ApsaraVideo VOD must be activated in the same region. For example, if you activate KMS and ApsaraVideo VOD in the China (Shanghai) region, specify cn-shanghai for this parameter. For more information about the IDs of other regions, see Region IDs of ApsaraVideo VOD. |
AccessKey
| The AccessKey ID and AccessKey secret of your Alibaba Cloud account or RAM user. For more information about how to obtain the AccessKey pair, see Obtain an AccessKey pair. |
httpserver
| The port number that you want to use to activate the service. |
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.ProtocolType;
import com.aliyuncs.vod.model.v20170321.DecryptKMSDataKeyRequest;
import com.aliyuncs.vod.model.v20170321.DecryptKMSDataKeyResponse;
import com.aliyuncs.profile.DefaultProfile;
import com.sun.net.httpserver.Headers;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import com.sun.net.httpserver.spi.HttpServerProvider;
import org.apache.commons.codec.binary.Base64;
import java.io.IOException;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URI;import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class HlsDecryptServer {
private static DefaultAcsClient client;
static {
// The region where KMS is used. The region must be the same as the region where the video resides.
String region = "";
// The AccessKey pair that is used to authorize access to KMS.
// The AccessKey pair of an Alibaba Cloud account has access permissions on all API operations. We recommend that you use the AccessKey pair of a RAM user to call API operations or perform routine O&M.
// We recommend that you not include your AccessKey pair (AccessKey ID and AccessKey secret) in your project code. Otherwise, the AccessKey pair may be leaked and the security of all resources within your account may be compromised.
// In this example, ApsaraVideo VOD reads the AccessKey pair from the environment variables to implement identity verification for API access. Before you run the sample code, configure the environment variables ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET.
String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
client = new DefaultAcsClient(DefaultProfile.getProfile(region, accessKeyId, accessKeySecret));
}
/**
* Note:
* 1. Receive a decryption request and obtain the EDK and token.
* 2. Call the decryption operation of KMS to obtain the plaintext key.
* 3. Decode the DK by using the Base64 algorithm and return the DK.
*/
public class HlsDecryptHandler implements HttpHandler {
/**
* Process the decryption request.
* @param httpExchange
* @throws IOException
*/
public void handle(HttpExchange httpExchange) throws IOException {
String requestMethod = httpExchange.getRequestMethod();
if ("GET".equalsIgnoreCase(requestMethod)) {
// Check whether the token is valid.
String token = getMtsHlsUriToken(httpExchange);
boolean validRe = validateToken(token);
if (!validRe) {
return;
}
// Obtain the ciphertext key from the video URL.
String ciphertext = getCiphertext(httpExchange);
if (null == ciphertext)
return;
// Decrypt the key in KMS and decode the key by using the Base64 algorithm.
byte[] key = decrypt(ciphertext);
// Configure the header.
setHeader(httpExchange, key);
// Return the key decoded by using the Base64 algorithm.
OutputStream responseBody = httpExchange.getResponseBody();
responseBody.write(key);
responseBody.close();
}
}
private void setHeader(HttpExchange httpExchange, byte[] key) throws IOException {
Headers responseHeaders = httpExchange.getResponseHeaders();
responseHeaders.set("Access-Control-Allow-Origin", "*");
httpExchange.sendResponseHeaders(HttpURLConnection.HTTP_OK, key.length);
}
/**
* Call the decryption operation of KMS to decrypt the key and decode the key by using the Base64 algorithm.
* @param ciphertext
* @return
*/
private byte[] decrypt(String ciphertext) {
DecryptKMSDataKeyRequest request = new DecryptKMSDataKeyRequest();
request.setCipherText(ciphertext);
request.setProtocol(ProtocolType.HTTPS);
try {
DecryptKMSDataKeyResponse response = client.getAcsResponse(request);
String plaintext = response.getPlaintext();
System.out.println("PlainText: " + plaintext);
// Note: You must decode the DK by using the Base64 algorithm.
return Base64.decodeBase64(plaintext);
} catch (ClientException e) {
e.printStackTrace();
return null;
}
}
/**
* Check whether the token is valid.
* @param token
* @return
*/
private boolean validateToken(String token) {
if (null == token || "".equals(token)) {
return false;
}
// TODO. You can customize the logic to check whether the token is valid.
return true;
}
/**
* Obtain the ciphertext key from the video URL.
* @param httpExchange
* @return
*/
private String getCiphertext(HttpExchange httpExchange) {
URI uri = httpExchange.getRequestURI();
String queryString = uri.getQuery();
String pattern = "CipherText=(\\w*)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(queryString);
if (m.find())
return m.group(1);
else {
System.out.println("Not Found CipherText Param");
return null;
}
}
/**
* Obtain the value of the token parameter.
*
* @param httpExchange
* @return
*/
private String getMtsHlsUriToken(HttpExchange httpExchange) {
URI uri = httpExchange.getRequestURI();
String queryString = uri.getQuery();
String pattern = "MtsHlsUriToken=(\\w*)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(queryString);
if (m.find())
return m.group(1);
else {
System.out.println("Not Found MtsHlsUriToken Param");
return null;
}
}
}
/**
* Start the service.
*
* @throws IOException
*/
private void serviceBootStrap() throws IOException {
HttpServerProvider provider = HttpServerProvider.provider();
// You can specify a custom port for listening. A web server can handle a maximum of 30 requests simultaneously on the same port.
HttpServer httpserver = provider.createHttpServer(new InetSocketAddress(8099), 30);
httpserver.createContext("/", new HlsDecryptHandler());
httpserver.start();
System.out.println("hls decrypt server started");
}
public static void main(String[] args) throws IOException {
HlsDecryptServer server = new HlsDecryptServer();
server.serviceBootStrap();
}}