Note: iPhone/iPod touch OS Version 3.0 is required.
The protocol and security specifics about iOS devices are covered in detail in the Internet Engineering Task Force draft-pantos-http-live-streaming-05 specification.
With the external method of AES-128 encryption, encryption keys are delivered by using an external URL. Wowza Media Server. There is also an internal method in which all media chunks and encryption keys are delivered using Wowza Media Server. For more information about how to use the internal method, see How to secure Apple HTTP Live Streaming (AES-128, internal method).
- Start by configuring an Wowza Media Server application for streaming by following one of the video on demand or live streaming tutorials. You will also need access to a web server.
- Configure an AES-128 key for encrypting the stream. We do this using the genkey utility that ships with Wowza Media Server in the [install-dir]/bin folder:
- Open a command shell and change directory to [install-dir]/bin.
- Enter the following command:
Windows:
Linux:Code:genkey.bat iphone [stream-name] [key-url]
Where [stream-name] is the name of the stream that will be encrypted and [key-url] is the URL that the iOS device will use to receive the key data (see the specifics on the [key-url] below). This command will generate the file [stream-name].key. An example command line is:Code:./genkey.sh iphone [stream-name] [key-url]
The output should look this:Code:genkey.bat iphone myStream https://mycompany.com/myStream.php
Code:key: B9A954F22ACD093BDEB80622EC7155BB url: https://mycompany.com/myStream.php Key file generated: myStream.key Copy file to: [install-dir]/keys
- Copy the file generated by the command-line tool to the [install-dir]/keys folder. See below for details about how to set up an application-specific keys folder.
- Open a command shell and change directory to [install-dir]/bin.
- Start Wowza Media Server and send the live stream to the server. When the live stream is published to the server, you will see the following log messages:
This indicates that the stream is being encrypted properly.Code:Encrypt iPhone stream: key: *[last-8-characters-of-key] Encrypt iPhone stream: url: [key-url]
The [key-url] is the URL that the devices will use to fetch the key to decrypt the stream. This is where you can control who can view your stream. If the request for this key returns a status of 403, then the device cannot decrypt and play the stream. If the key is returned, then the stream will be decrypted and played. We suggest that this URL be protected by HTTPS so that the key is not sent over the Internet in the clear. The key information must be sent as a packed array of 16 octets in binary format with the following header information:
Code:
Content-Type: binary/octet-stream Pragma: no-cache
ASP.NET example
Code:
<%@ Page Language="C#" %>
<%
Boolean isValid = true;
if (!isValid)
{
Response.Status = "403 Forbidden";
}
else
{
Response.AddHeader("Content-Type", "binary/octet-stream");
Response.AddHeader("Pragma", "nocache");
String keyStr = "DE51A7254739C0EDF1DCE13BBB308FF0";
int len = keyStr.Length/2;
byte[] keyBuffer = new byte[len];
for (int i=0;i<len;i++)
keyBuffer[i] = Convert.ToByte(keyStr.Substring(i*2, 2), 16);
Response.BinaryWrite(keyBuffer);
Response.Flush();
Response.End();
}
%>
Code:
<%@ page import="java.util.*,java.io.*" %>
<%
boolean isValid = true;
if (!isValid)
{
response.setStatus( 403 );
}
else
{
response.setHeader("Content-Type", "binary/octet-stream");
response.setHeader("Pragma", "no-cache");
String keyStr = "DE51A7254739C0EDF1DCE13BBB308FF0";
int len = keyStr.length()/2;
byte[] keyBuffer = new byte[len];
for (int i=0;i<len;i++)
keyBuffer[i] = (byte)Integer.parseInt(keyStr.substring(i*2, (i*2)+2), 16);
OutputStream outs = response.getOutputStream();
outs.write(keyBuffer);
outs.flush();
}
%>
Code:
<?php
function hex2bin($h)
{
if (!is_string($h))
return null;
$r = '';
for ($a=0;$a<strlen($h);$a+=2)
{
$r .= chr(hexdec($h{$a}.$h{($a+1)}));
}
return $r;
}
$isValid = true;
if (! $isValid)
{
header('HTTP/1.0 403 Forbidden');
}
else
{
header('Content-Type: binary/octet-stream');
header('Pragma: no-cache');
echo hex2bin('DE51A7254739C0EDF1DCE13BBB308FF0');
exit(); // this is needed to ensure cr/lf is not added to output
}
?>
These examples are provided as-is with no expressed warranty. Feel free to modify or distribute them without restriction.
[install-dir]
Windows (default): C:\Program Files\Wowza Media Systems\Wowza Media Server [version]
Mac OS X: /Library/WowzaMediaServer
Linux: /usr/local/WowzaMediaServer
Note: By default all applications are configured to use the same keys folder, which can lead to stream name conflicts. To configure a keys folder on a per-application basis, open [install-dir]/conf/[application]/Application.xml in a text editor and change the Streams/KeyDir property value. If you set this value to an empty value (zero length), then it defaults to:
Code:
[install-dir]/applications/[application]/keys/[appInstance]
Note: In Wowza Media Server 2 (preview 7) or later, any query parameters passed as part of the playlist.m3u8 URL as well as the wowza session id will be passed to the key URL. For example, if you play a stream using the URL:
And the key URL is defined as:
Then the URL sent to myStream.php will include the following query parameters:
Code:
http://[wowza-ip-address]:1935/live/myStream/playlist.m3u8?userid=12345
Code:
https://mycompany.com/myStream.php?keyinfo=securekey
Code:
https://mycompany.com/myStream.php?keyinfo=securekey&userid=12345&wowzasessionid=345234
Note: To test AES encryption, see How to test AES encryption for Apple HTTP Live Streaming.
- Click here, if you are having problems or would like to discuss this article.
- Leave a comment below, if there is some aspect of this article you would like to see changed or improved.


Article List
Categories
Wowza Media