Protect streaming using SecureToken in Wowza Streaming Engine

Wowza Streaming Engine™ media server software provides SecureToken playback protection for all supported streaming protocols and includes hashing options for generating the security token that's exchanged between Wowza Streaming Engine and its clients. SecureToken is a challenge/response system that helps to protect content against spoofing threats. Each connection is protected by a random key (hash) and a password (shared secret).

Note: Wowza Streaming Engine 4.1 or later is required for all protocols except WebRTC. For WebRTC SecureToken playback protection, Wowza Streaming Engine 4.8.11 or later is required.

Overview


Wowza Streaming Engine has a SecureToken module that provides playback protection using a security token that's exchanged between the server and clients. You can enable Wowza Streaming Engine to use a secure hash algorithm (SHA) for generating a security token for playback protection over all supported streaming protocols. The supported secure hash algorithms are: 

  • SHA-256
     
  • SHA-384
     
  • SHA-512

When a player requests a stream from Wowza Streaming Engine, the request URL or the WebSocket JSON message for WebRTC has a set of public SecureToken query parameters, one of which is a hash generated by the client webpage. The hash is generated from the content path, the SecureToken query parameters, and a private shared secret. After receiving the request, the SecureToken module uses an algorithm to generate a hash based on the content path, the received SecureToken query parameters, and the private shared secret. Wowza Streaming Engine compares this hash to the hash it gets from the client. If the values don't match, it rejects the connection.

Setting up SecureToken protection in Wowza Streaming Engine


This section shows you how to set up SecureToken playback protection in Wowza Streaming Engine Manager.  

  1. In the Applications contents panel, click the name of your application, and then click Playback Security.

  1. Click Edit.
     
  2. Under SecureToken, select the type of secure token playback protection that you want to use. We recommend Protect all protocols using hash (SecureToken version 2), which protects all streaming protocols using the latest hash algorithms.



     
  3. Under Shared Secret, enter a string of alphanumeric (a - z, A - Z, 0 - 9) characters in the box, or click Generate SecureToken Shared Secret to enter a random string of alphanumeric characters.


     

    Important: Your web server administrator must use this same shared secret value to generate the client-side hash when the client webpage is generated. JavaScript code shouldn't be used in the client webpage to generate the hash as the code is visible in the webpage source and would pose a potential security risk.
  4. If you opted to protect all streaming protocols using a hash algorithm, specify the hashing options:
     
    1. Select a hash algorithm in the Hash Algorithm list.



      You can enable additional security by selecting Include client IP address in hash generation, which causes the hash that's generated to be unique for each connecting client.
       

      Note: Due to network complexities, the client webpage that generates the client-side hash may use a client IP address that's different from the IP address detected by Wowza Streaming Engine. This will cause Wowza Streaming Engine to generate a hash that's different from the hash it gets from the client and the connection will be rejected.
    2. Enter a query parameter prefix in the Hash Query Parameter Prefix box or use the default value (wowzatoken).



      The prefix value can only have the following characters that are safe to use in URLs: alphanumeric characters (a - z, A - Z, 0 - 9), percent sign (%), period (.), underscore (_), tilde (~), and hyphen (-).
  5. Click Save.

SecureToken query parameters


SecureToken public query parameters are included in request URLs sent from clients to Wowza Streaming Engine. Wowza Streaming Engine must be able to identify query parameters that are used with SecureToken in request URLs so that it can include them when generating its hash; therefore, each query parameter to be used with SecureToken must begin with a SecureToken query parameter prefix. Other query parameters in request URLs should not use a SecureToken query parameter prefix as this will cause Wowza Streaming Engine to generate an improper hash. The examples in this section use the SecureToken query parameter prefix wowzatoken.

  • hash – (Required) The hash generated at the client as a URL-safe Base64-encoded string. URL-safe Base64 encoding replaces the '+' character with the '-' character and the '/' character with the '_' character. For example:

wowzatokenhash=VSNlS5S2Na5KxwwiVLXIcHwC90CF2lHdmCm9v_8Bh0o=

  • starttime – (Optional) The time (in UTC seconds) when SecureToken playback security starts. If this parameter isn't included in the URL or if the parameter is included with a value of 0, SecureToken playback security is enabled immediately. Player connections that occur before the start time will be rejected. For example:

wowzatokenstarttime=1405036800 (11 July 2014 00:00:00 GMT)

  • endtime – (Optional) The time (in UTC seconds) when SecureToken playback security stops. This parameter takes a 10-digit epoch numeric string, which is is specific to the second.

    Note: A 13-digit (millisecond) or 16-digit (microsecond) numeric string cannot be used.
    If this parameter isn't included in the URL or if the parameter is included with a value of 0, SecureToken playback security is always enabled, the SecureToken doesn't expire, and security may be more vulnerable. Player connections that occur after the end time will be rejected. For example:

wowzatokenendtime=1405123200 (12 July 2014 00:00:00 GMT, 24 hours from the starttime.)

Note: We recommend that you specify an endtime, as it's required in most use cases; however, a SecureToken that doesn't expire may be needed in some situations, so you can omit this parameter if necessary.
  • Custom parameters – You can add custom query parameters to be used in the generation of the hash. These parameters can be key/value pairs or single key values.
Note: WebRTC does not support using custom query parameters for SecureToken.

Pairs look like this:

wowzatokenCustomParameter=myValue

A single key value looks like this:

wowzatokenCustomParameter

You can add a unique customer-specific hash parameter to ensure that a unique SecureToken hash is generated per customer, like this:

wowzatokenCustomerHash=N4asd45ESSdkLHfa3qwer_0923zdghMLOE_seda375oz=

Hash generation


Wowza Streaming Engine and its clients must follow certain rules to ensure the string that's created and hashed is identical and that the correct hash is generated in both places. 

Important: The client web server should generate the hash when it generates the client webpage. You shouldn't use JavaScript code in the client webpage to generate the hash as the code is visible in the webpage source and would pose a potential security risk.
  1. Start the string with the content path to the streaming asset (live stream name or VOD file name). The content path is the part of the URL that starts with the application name (excluding the '/' that precedes the application name) and continues through to the end of the stream name or file name. Be sure to exclude all HTTP request keywords after the stream name or file name (for example, /manifest.m3u8, /media.ts, and so on).
  2. Append the '?' character to the path that you created in the previous step. This character separates the content path from the public SecureToken query parameters that follow.
  3. Append the public SecureToken query parameters, shared secret, and client IP address (if applicable) to the '?' character that you created in the previous step. These items must be in alphabetical order and separated by the '&' character.

The following examples use SHA-256, in binary, to calculate the hash.

HLS example

This example is based on an HLS VOD request where no application instance is specified in the URL. The prefix that's used to identify the public query parameters is set to a custom value. A custom public query parameter is included in the hash generation, as well as the client IP address, and the SecureToken start and end times are specified.

Content URL: http://192.168.1.1:1935/vod/sample.mp4/playlist.m3u8

Content path: vod/sample.mp4

SecureToken prefix: myTokenPrefix

Custom SecureToken public query parameter: myTokenPrefixCustomParameter=abcdef

Token start time: myTokenPrefixstarttime=1395230400

Token end time: myTokenPrefixendtime=1500000000


The parameters used to create the string used for hashing: 

  • myTokenPrefixstarttime=1395230400
  • myTokenPrefixendtime=1500000000
  • myTokenPrefixCustomParameter=abcdef
  • mySharedSecret
  • 192.168.1.2

String used for hashing (in required alphabetical order):

vod/sample.mp4?192.168.1.2&mySharedSecret&myTokenPrefixCustomParameter=abcdef&myTokenPrefixendtime=15000 00000&myTokenPrefixstarttime=1395230400


HLS manifest request URL sent to Wowza Streaming Engine:


http://192.168.1.1:1935/vod/sample.mp4/playlist.m3u8?myTokenPrefixstarttime=1395230400&myTokenPrefixendtime=1500000000&myTokenPrefixCustomP arameter=abcdef&myTokenPrefixhash=TgJft5hsjKyC5Rem_EoUNP7xZvxbqVPhhd0GxIcA2oo=

RTSP example

This example is based on an RTSP VOD request where the application instance is specified in the URL. The default query parameter prefix (wowzatoken) is used, a custom public query parameter is included in the hash generation, and the SecureToken end time is specified. The client IP address isn't included in the hash generation and the SecureToken start time isn't specified (SecureToken playback security is enabled immediately).


Content URL: rtsp://192.168.1.1:1935/vod/sample.mp4

Content path: vod/_myInstance_/sample.mp4

Custom SecureToken public query parameter: wowzatokenCustomParameter=abcdef

Token end time: wowzatokenendtime=1500000000


The parameters used to create the string used for hashing:

 

  • wowzatokenendtime=1500000000
  • wowzatokenCustomParameter=abcdef
  • xyzSharedSecret

String used for hashing (in required alphabetical order):


vod/_myInstance_/sample.mp4?wowzatokenCustomParameter=abcdef&wowzatokenendtime=1500000000&xyzSharedSecret


RTSP URL sent to Wowza Streaming Engine:


rtsp://10.0.2.31:1935/vod/_myInstance_/sample.mp4?wowzatokenendtime=1500000000&wowzatokenCustomParameter=abcdef&wowzatokenhash=kJ591xB2lT-X0OA9UdoRx61uwp6A_IoSc_jCx_9h1l8=

WebRTC example

This example is based on a WebRTC request with a live application named webrtc and stream named myStream. No application instance is specified in the URL. The prefix that's used to identify the starttime and endtime query parameters is set to a custom value, and the SecureToken start and end times are specified. WebRTC does not support using custom query parameters.

Content URL: wss://5ab4321c0d123.streamlock.net:443/webrtc-session.json

Content path: webrtc/myStream

SecureToken prefix: myTokenPrefix

Token start time: myTokenPrefixstarttime=1614714535

Token end time: myTokenPrefixendtime=1614814635

The parameters used to create the string used for hashing:

  • myTokenPrefixstarttime=1614714535
  • myTokenPrefixendtime=1614814635
  • xyzSharedSecret

String used for hashing (in required alphabetical order):

webrtc/myStream?myTokenPrefixendtime=1614814635&myTokenPrefixstarttime=1614714535&xyzSharedSecret

Wowza Streaming Engine receives the SecureToken hash from WebRTC players in the WebSocket signaling JSON message rather than a request URL. WebRTC JSON message sent to Wowza Streaming Engine:

{
"direction":"play",
"command":"getOffer", 
"streamInfo":{
  "applicationName":"webrtc", 
  "streamName":"myStream" 
  }, 
"userData":{ 
  "iceServers":[] 
  }, 
"secureToken":{
  "hash":"SAOBJs_B43SOOqRNLWovcC2H13fVfAqRtH1SXumOb84=", 
  "starttime":"1614714535", 
  "endtime":"1614814635" 
  } 
} 

For WebRTC SecureToken, as with other protocols, the client web server should generate the hash when it generates the client webpage so that the client webpage doesn't expose SecureToken information in its source code.

SecureToken property reference


This section describes the application properties that you can use to set up SecureToken playback security in the Wowza Streaming Engine XML configuration. You can set these properties by adding them to the <Properties> container at the end of the [install-dir]/conf/[application-name]/Application.xml file. Be sure to get the correct <Properties> container—there are several in Application.xml

Notes:
  • If you already set up SecureToken playback security in Wowza Streaming Engine Manager, you do not need to configure the properties in Application.xml because they are added by Wowza Streaming Engine Manager.
  • You must restart the Wowza Streaming Engine after configuring the properties.
  • securitySecureTokenVersion – Selects the SecureToken version to use. Set to 2 to protect playback over all supported streaming protocols using a hash algorithm.
  • securitySecureTokenSharedSecret – Specifies the string that's used as the shared secret by Wowza Streaming Engine and client for all versions of SecureToken. The string must contain only alphanumeric characters (a - z, A - Z, 0 - 9).
  • securitySecureTokenHashAlgorithm – When securitySecureTokenVersion is set to 2, this property specifies the hash algorithm that's used to generate the hash. Valid values are SHA-256, SHA-384, and SHA-512.
  • securitySecureTokenQueryParametersPrefix – When securitySecureTokenVersion is set to 2, this property specifies the prefix that's used on all SecureToken query parameters. Valid values must use only the following characters: alphanumeric (a - z, A - Z, 0 - 9), percent (%), period (.), underscore (_), tilde (~), and hyphen (-)[/B]
  • securityDebugLogRejections – Used for all securitySecureTokenVersion values. Set to true to log rejected connection attempts.
Note: To add this property in Wowza Streaming Engine Manager, see Additional logging.
  • securityDebugLogDetails – Used for all securitySecureTokenVersion values. Set this value to true to enable SecureToken debug logging.
Notes:
  • To add this property in Wowza Streaming Engine Manager, see Additional logging.
  • Enabling debug logging can produce a lot of log entries, which can create very large log files.

SecureToken parameters encoded into manifest and media responses


The HLS and MPEG-DASH protocols include SecureToken query parameters in the submanifest and media names returned in request responses. 

  • These query parameters are the parameters that Wowza Streaming Engine receives with the first manifest request.
  • The parameters are Base64-encoded, where the '_' character is replaced by the '!' character.
  • The parameters are identified in the submanifest or media name in the response by the _tk token followed by the modified Base64-encoded string.

HLS example

Request: http://192.168.1.1:1935/vod/sample.mp4/playlist.m3u8?myTokenPrefixstarttime=1395230400&myTokenPrefixendtime=1500000000&myTokenPrefixCustomP arameter=abcdef&myTokenPrefixhash=o4ICgenL8-KU2uktN6XvrN8kCFlXBl7k65PorS2odRk=


Submanifest name in response:

chunklist_w1955037621_tkd293emF0b2tlbnN0YXJ0dGltZT0xMzk1MjMwNDAwJndvd3phdG9rZW5lbmR0aW1lPTE1MDAwMDAwMDAmd293emF0b2tlbmhhc2g9 eG0xQW1INUtRWDl6ZVdzTEQ4NzJmc1pCZFptMXloSlFuUGxSN25wclVwQT0=.m3u8

  

Configuration settings in logs


When the application starts, the following SecureToken configuration settings are logged in [install-dir]/logs/wowzastreamingengine_access.log:

If SecureToken playback protection is set to use a hash algorithm for all protocols (securitySecureTokenVersion is set to 2): 

INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using SecureToken Version 2, play security enabled for RTMP, RTSP, HLS, and Dash protocols
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using SHA-256 for play security
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: securitySecureTokenIncludeClientIPInHash: true
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: SecureToken query parameters prefix is wowzatoken
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: SecureToken token start time query parameter is wowzatokenstarttime
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: SecureToken token end time query parameter is wowzatokenendtime
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: SecureToken token hash query parameter is wowzatokenhash


If SecureToken is turned off (securitySecureTokenVersion is not set): 

INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: securitySecureTokenVersion property is missing, using SecureToken Version 1, play security enabled for RTMP only
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using SecureToken Version 1, play security enabled for RTMP only

Troubleshooting


Additional logging

You can turn on the securityDebugLogRejections and securityDebugLogDetails application properties to log additional information, which can help to identify configuration problems. To add these properties in Wowza Streaming Engine Manager, you must set them as custom properties in the application. See Add a custom property for details.

The following are the values that must be used in the Add Custom Property dialog box for each custom logging property:


securityDebugLogRejections

Path
Name
Type
Value
Root/ApplicationsecurityDebugLogRejectionsBooleantrue


securityDebugLogDetails

Path
Name
Type
Value
Root/ApplicationsecurityDebugLogDetailsBooleantrue


Session rejected due to non-matching hash values

The following is logged if an HTTP session is rejected because the server and client hashes don't match. 

Note: The securityDebugLogDetails property must be enabled.
INFO application app-start _definst_ security-vod/_definst_
INFO server comment - ModuleCoreSecurity.onStreamCreate[security-vod/_definst_]: Client is null. No Secure Token check.
INFO cupertino connect 1549778894 -
INFO stream create sample.mp4 -
INFO server comment - ModuleCoreSecurity.onHTTPSessionCreate[security-vod/_definst_/sample.mp4]: All security checks passed.
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:current time stamp: 1403636858
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:sessionId: 1549778894
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:hashReceived: 1Rw3ZGgn0-peLuu39yqEOQolqj_xWRJ1U3na2emyL8U=
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:creating httpToken for SessonId:1549778894 uri:/security-vod/sample.mp4/playlist.m3u8?wowzatokenstarttime=1395230400&wowzatokenendtime=1500000000&wowzatokenhash=1Rw3ZGgn0-peLuu39yqEOQolqj_xWRJ1U3na2emyL8U=
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:client IP: 10.0.2.31
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:hashCalculated: IF0Ai8BCqLPf-fEpIbJ5HT6xUDWa6o1W43FLTRfQZRU=
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:string hashed: security-vod/sample.mp4?sharedsecret&wowzatokenendtime=1500000000&wowzatokenstarttime=1395230400
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:token start time stamp: 1395230400
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:token end time stamp: 1500000000
INFO server comment - [security-vod/_definst_]SecureTokenDef:Hash 1Rw3ZGgn0-peLuu39yqEOQolqj_xWRJ1U3na2emyL8U=, doesn't match hash calculated, IF0Ai8BCqLPf-fEpIbJ5HT6xUDWa6o1W43FLTRfQZRU=
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:client IP: 10.0.2.31
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:hashCalculated: 1FGT5uuUaVQPFBB-NIawz41I0pAtjQbrezyMGlXO3aE=
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:string hashed: security-vod/sample.mp4?sharedsecret&wowzatokenendtime=1500000000&wowzatokenstarttime=1395230400
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:token start time stamp: 1395230400
INFO server comment - [security-vod/_definst_]ModuleCoreSecurity:token end time stamp: 1500000000
INFO server comment - [security-vod/_definst_]SecureTokenDef:Hash 1Rw3ZGgn0-peLuu39yqEOQolqj_xWRJ1U3na2emyL8U=, doesn't match hash calculated, 1FGT5uuUaVQPFBB-NIawz41I0pAtjQbrezyMGlXO3aE=
WARN server comment - HTTPStreamerAdapterCupertinoStreamer.onPlaylist[security-vod/sample.mp4/playlist.m3u8?wowzatokenstarttime=1395230400&wowzatokenendtime=1500000000&wowzatokenhash=1Rw3ZGgn0-peLuu39yqEOQolqj_xWRJ1U3na2emyL8U=]: Session not accepted[1549778894]
INFO stream destroy sample.mp4 -
INFO cupertino disconnect 1549778894 -


The first log entry in orange is the string used by the server to generate its hash. This string is in the required alphabetical order and must be identical to the string used to generate the client-side hash that was sent to the server.


The second log entry in orange is the server hash and the received hash. The received hash is the exact string received via the query parameters.