目录
综述
Wowza Streaming Engine的SecureToken功能的相关配置
SecureToken的url查询参数
生成Hash code
Flash 播放器端的SecureToken设置
SecureToken 相关参数参考
SecureToken 查询参数在编码后被返回到Submanifest中
在log日志中会显示相关配置参数
故障排查
综述
Wowza Streaming Engine (4.1.0 及以上版本) 有一个升级版的SecureToken 功能,它可以用一个security token提供针对播放流的保护。 你可以设置使用不同的Hash算法来生成security token,支持的算法包括如下:
- SHA-256
- SHA-384
- SHA-512
当播放器请求一个Wowza Streaming Engine的流时,这个Url需要携带一些SecureToken 查询参数, 其中一个是经hash算法计算后的值,它由播放器端生成的。 这个Hash的计算,其原始字符串是根据content path、SecureToken 查询参数以及共享密钥的组合而形成的。当Wowza收到请求后,SecureToken模块就会根据content path、SecureToken 查询参数以及功能密钥来计算Hash值。 然后Wowza就会将自己计算的Hash值和来自播放请求中的Hash值做对比,如果不匹配,则请求被拒绝。
Wowza Streaming Engine的SecureToken功能的相关配置
这个部分向您介绍了如何在Wowza Streaming Engine Manager中为自带的vod应用配置SecureToken播放保护功能。
- 确定Wowza Streaming Engine Manager处于正常运行状态,要了解更多,请参考Wowza Streaming Engine 软件的启动和停止.
-
在Applications菜单,点击vod, 然后点击Playback Security.
点击Edit来访问SecureToken配置选项。
-
在SecureToken部分,选择你要采用的secure token 播放保护的类型。
我们推荐你选择Protect all protocols using hash (SecureToken version 2).
它可以适用于所有流传输协议,并使用了最新的Hash算法。
如果只是针对rtmp协议的,可以选择Protect RTMP protocol using TEA (SecureToken version 1).
-
在Shared Secret, 输入共享密钥(有效字符包括a - z, A - Z, 0 - 9),或者点击Generate SecureToken Shared Secret 按钮来随机生成一个。
重要: 你的视频播放网站必须用同样的共享密钥来生成Hash code。最好不要用JavaScript代码来做这个事(会有潜在的风险),应该是服务端生成页面时做。
-
如果你选择了用Hash算法保护所有的流传输协议,继续做如下配置(如果你选择只针对RTMP的保护,可以跳过这一段):
-
在Hash Algorithm的下拉框中选择你需要的算法。
如果你以前用过针对RTMP的保护,为了继续兼容,你可以在Use TEA for RTMP token security的复选框中打勾,其它流传输协议依然采用你下拉框中选择的Hash算法。
为了更安全,你还可以在Include client IP address in hash generation复选框前打勾。这让会导致Wowza在计算Hash时,将客户端IP地址做为计算Hash的一部分。
注意:这个功能要谨慎使用,因为网络情况会比较复杂,比如Nat,比如IP地址变化等。这会导致你在客户端得到的IP地址和WOwza检测到的IP地址不符,从而导致Hash匹配失败,最终会话连接被拒绝。 -
在Hash Query Parameter Prefix的输入框中输入一个query parameter前缀,或者用默认的(wowzatoken).
这个前缀的有效字符范围是 (a - z, A - Z, 0 - 9), 百分号(%), 点(.), 下划线(_), 波浪符(~), 以及横杠(-).
-
在Hash Algorithm的下拉框中选择你需要的算法。
- 点击Save.
SecureToken的URL查询参数
SecureToken 的URL查询参数是客户端请求Wowza流服务时,在URL中发送给Wowza的一些附加参数。Wowza必须能够识别URL中的这些参数,这样才能在计算Hash时将其加入进去,因此这些参数必须以SecureToken query parameter 前缀为开始。 这里的例子使用wowzatoken为前缀。
hash
(必须的) 在客户端生成Hash时的字符串必须是 URL-safe Base64-encoded格式的。URL-safe Base64 encoding 将用'-'替换'+',用'_'替换'/'。也就是说,你要先计算Hash值后,再对这个Hash值做Base64编码,然后对这个Base64编码后的字符串做一个字符替换(用'-'替换'+',用'_'替换'/')。
例如: wowzatokenhash=VSNlS5S2Na5KxwwiVLXIcHwC90CF2lHdmCm9v_8Bh0o=
starttime
(可选) 这个时间(UTC seconds格式) 是SecureToken 播放安全功能的启用时间。如果URL中没有带这个时间或者这个时间的值为0,则SecureToken 播放安全功能立即启用。 在这个时间之前发生的播放连接都将被拒绝。例如: wowzatokenstarttime=1405036800 (11 July 2014 00:00:00 GMT)
endtime
(可选) 这个时间(UTC seconds格式) 是SecureToken 播放安全功能停止的时间。如果URL中没有带这个时间或者这个时间的值为0, 则SecureToken 播放安全功能一直保持启用状态。SecureToken 不会过期, 但这样是不太安全的。在这个时间之后发生的Player连接将被拒绝。例如: wowzatokenendtime=1405123200 (12 July 2014 00:00:00 GMT, 24 hours from the starttime.)
注意: 我们推荐你设置一个endtime时间,在大多数场景这样会更安全;然而有时候你希望SecureToken 永不过期。所以,你要根据你的需求来考虑使用需要这个参数。
自定义参数
你可以添加一些自定义参数,用于Hash的计算,这些参数可以是key/value对或者单独的值。
例子1 (key/value pair): wowzatokenCustomParameter=myValue
例子2 (key value): wowzatokenCustomParameter
例子2 (key value): wowzatokenCustomParameter
举例说明, 你可以添加一个用户的唯一标识,确保每一个用户有一个唯一的Hash值。
例子: wowzatokenCustomerHash=N4asd45ESSdkLHfa3qwer_0923zdghMLOE_seda375oz=
Hash的生成
这里介绍了生成Hash的规则,你的客户端(相对于Wowza而言)必须遵循这个规则,才能确保你计算的Hash和Wowza计算的Hash是一直的。
重要:你最好是在服务端计算Hash然后返回给客户端,而不是在客户端(比如Javascript)生成Hash,因为那样会暴露代码并导致一些安全隐患。
-
计算Hash的字符串最开头是你的流内容路径(直播流名字或VOD文件名)。内容路径从Wowza的应用名开始(不要用'/'开始)并跟上完整的流名字。
注意不要在流名字后加上HTTP请求的类型关键字符(例如,/manifest.m3u8, /media.ts, /Manifest, /manifest.f4v等等)。
请参考下面的例子。
- 在上一步的内容路径后面加上'?'这个分隔符将内容路径从SecureToken 查询参数中区分出来。
- 在上一步的"?"后面加上SecureToken 查询参数、共享密钥以及客户端IP地址(如果前面选择了在Hash中加入IP地址的功能)。这些参数都必须按阿拉伯字母顺序来排列,并以'&'分隔开。
例子
下面的例子使用SHA-256 计算hashHLS 的例子
这个例子非常简单,就是播放wowza自带的sample.mp4文件。 使用的前缀是一个自定义的值。 在计算Hash的字符串中包含了一个自定义参数,以及客户端IP地址、起始时间和结束时间。原始的播放URL: http://192.168.1.1:1935/vod/sample.mp4/playlist.m3u8
内容路径: vod/sample.mp4
自定义的SecureToken 前缀: myTokenPrefix
自定义的 SecureToken 查询参数: myTokenPrefixCustomParameter=abcdef
Token 的开始时间: myTokenPrefixstarttime=1395230400
Token 的结束时间: myTokenPrefixendtime=1500000000
下面是用于计算Hash的字符串的各个组成部分(下面的列表并没有按阿拉伯字母顺序来):
- myTokenPrefixstarttime=1395230400
- myTokenPrefixendtime=1500000000
- myTokenPrefixCustomParameter=abcdef
- mySharedSecret
- 192.168.1.2
用于计算Hash的字符串(按阿拉伯字符顺序排列):
vod/sample.mp4?192.168.1.2&mySharedSecret&myTokenPrefixCustomParameter=abcdef&myTokenPrefixendtime=1500000000&myTokenPrefixstarttime=1395230400
最终发送给Wowza的HLS URL:
http://192.168.1.1:1935/vod/sample.mp4/playlist.m3u8?myTokenPrefixstarttime=1395230400&myTokenPrefixendtime=1500000000&myTokenPrefixCustomParameter=abcdef&myTokenPrefixhash=TgJft5hsjKyC5Rem_EoUNP7xZvxbqVPhhd0GxIcA2oo=
RTSP的例子
还是以播放sample.mp4文件为例。 前缀用的是默认的设置(wowzatoken),在计算Hash的字符串中包含了一个自定义参数和SecureToken的结束时间。 没有带客户端IP地址,也没有带SecureToken的开始时间(SecureToken 播放安全立即生效)。原始的播放 URL: rtsp://192.168.1.1:1935/vod/sample.mp4
内容路径: vod/_myInstance_/sample.mp4
自定义的 SecureToken 查询参数: wowzatokenCustomParameter=abcdef
Token的结束时间: wowzatokenendtime=1500000000
用于计算Hash的字符串的各个组成部分(下面的列表并没有按阿拉伯字母顺序来):
- wowzatokenendtime=1500000000
- wowzatokenCustomParameter=abcdef
- xyzSharedSecret
用于计算Hash的字符串(按阿拉伯字母顺序排列):
vod/_myInstance_/sample.mp4?wowzatokenCustomParameter=abcdef&wowzatokenendtime=1500000000&xyzSharedSecret
最终发送给Wowza的RTSP URL:
rtsp://10.0.2.31:1935/vod/_myInstance_/sample.mp4?wowzatokenendtime=1500000000&wowzatokenCustomParameter=abcdef&wowzatokenhash=kJ591xB2lT-X0OA9UdoRx61uwp6A_IoSc_jCx_9h1l8=
Flash 播放器端的SecureToken设置
如果你选择了针对所有流传输协议统一的hash算法,你必须将SecureToken 查询参数传递给Flash 播放器,这样它才能被发送给Wowza Streaming Engine。 例如,以JW Player 6.8为例,可以按下面来配置JW Player:
jwplayer("player").setup({ autostart: false, file: "<url>", rtmp: { bufferlength: 5 }, width: "600", height: "337", });
如果你选择针对RTMP协议用Tiny Encryption Algorithm (TEA)算法,你必须用ActionScript代码来相应SecureToken challenge。 要了解更多细节,请参考如何用SecureToken对RTMP流进行保护?。
SecureToken 相关参数参考
下面介绍了一些SecureToken功能相关的参数配置,这些参数可以配置在Wowza应用的属性中。你可以在这个应用的application.xml文件中配置,也可以用Wowza Streaming Engine Manager管理页面来配置。
注意:
- 配置完成后,要重启Wowza,才能让配置生效。
securitySecureTokenVersion
选择SecureToken 的版本。<Property> <Name>securitySecureTokenVersion</Name> <Value>2</Value> <Type>Integer</Type> </Property>
- 1 - 版本1. 这个版本在针对RTMP协议时,采用Tiny Encryption Algorithm (TEA)算法。
- 2 - 版本2. 这个版本针对所有流传输协议采用统一的Hash算法。
securitySecureTokenSharedSecret
设置共享密钥,有效字符包括(a - z, A - Z, 0 - 9).<Property> <Name>securitySecureTokenSharedSecret</Name> <Value>sharedsecret</Value> <Type>String</Type> </Property>
securitySecureTokenUseTEAForRTMP
当securitySecureTokenVersion 被设置为 2时,如果下面这个参数被设置为true就会针对RTMP协议单独使用TEA算法。<Property> <Name>securitySecureTokenUseTEAForRTMP</Name> <Value>false</Value> <Type>Boolean</Type> </Property>
securitySecureTokenHashAlgorithm
当securitySecureTokenVersion 被设置为 2时,下面这个参数设置了具体的Hash算法。<Property> <Name>securitySecureTokenHashAlgorithm</Name> <Value>SHA-256</Value> <Type>String</Type> </Property>
securitySecureTokenQueryParametersPrefix
当securitySecureTokenVersion被设置为2, 下面这个参数设置了针对所有SecureToken 查询参数的前缀。<Property> <Name>securitySecureTokenQueryParametersPrefix</Name> <Value>wowzatoken</Value> <Type>String</Type> </Property>
securityDebugLogRejections
下面这个参数适用于所有的securitySecureTokenVersion。将这个参数设置为true会将所有拒绝连接的消息记录到日志中。<Property> <Name>securityDebugLogRejections</Name> <Value>false</Value> <Type>Boolean</Type> </Property>
注意:要在Streaming Engine Manager管理界面中添加这个参数,请参考添加Log日志.
securityDebugLogDetails
下面的参数适用于所有的securitySecureTokenVersion。当设置为true时可以让SecureToken模块输出更详细的debug日志。<Property> <Name>securityDebugLogDetails</Name> <Value>false</Value> <Type>Boolean</Type> </Property>
注意:
- 要在Streaming Engine Manager管理界面中添加这个参数,请参考添加Log日志.
- 打开了这个日志后,会导致Wowza生成很大的日志文件.
SecureToken parameters encoded into manifest and media responses
在使用Apple HLS, Adobe HDS, and MPEG-DASH 协议时,这些协议会将SecureToken 查询参数返回在http响应的Submanifest中。
- 这些参数是在前面的请求中,Wowza接收到的参数。
- 这些参数是Base64编码后的,'_'将被替换为'!'。
- 这些参数在返回时位于_tk后面。
Apple HLS 的例子
请求: http://192.168.1.1:1935/vod/sample.mp4/playlist.m3u8?myTokenPrefixstarttime=1395230400&myTokenPrefixendtime=1500000000&myTokenPrefixCustomP arameter=abcdef&myTokenPrefixhash=o4ICgenL8-KU2uktN6XvrN8kCFlXBl7k65PorS2odRk=响应中的Submanifest:
chunklist_w1955037621_tkd293emF0b2tlbnN0YXJ0dGltZT0xMzk1MjMwNDAwJndvd3phdG9rZW5lbmR0aW1lPTE1MDAwMDAwMDAmd293emF0b2tlbmhhc2g9 eG0xQW1INUtRWDl6ZVdzTEQ4NzJmc1pCZFptMXloSlFuUGxSN25wclVwQT0=.m3u8
注意: Smooth Streaming 协议返回的Submanifest是正常的SecureToken 查询参数,不是Base64编码的。
在log日志中会显示相关配置参数
当Wowza应用启动后,在[install-dir]/logs/wowzastreamingengine_access.log文件中你会看到下面的参数会显示出来:
假设SecureToken功能被设置为所有协议使用统一的Hash算法(securitySecureTokenVersion被设置为2):
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using SecureToken Version 2, play security enabled for RTMP, RTSP, HLS, HDS, SmoothStreaming 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
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
假设SecureToken功能被设置为所有协议使用统一的Hash算法(securitySecureTokenVersion被设置为2) 但又设置了针对RTMP协议使用Tiny Encryption Algorithm (TEA)(securitySecureTokenUseTEAForRTMP 被设置为true):
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using TEA for RTMP play security
如果SecureToken 设置为仅针对RTMP协议,并且使用TEA(securitySecureTokenVersion被设置为11):
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using SecureToken Version 1, play security enabled for RTMP only
假设SecureToken功能被关闭(securitySecureTokenVersion 没有被设置):
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
INFO server comment - ModuleCoreSecurity.onAppStart[security-vod/_definst_]: Play: using SecureToken Version 1, play security enabled for RTMP only
故障排查
添加log日志
你可以打开securityDebugLogRejections 和 securityDebugLogDetails 参数,这样可以在日志中打印更多的日志,帮助我们定位一些配置上的问题。 要在Wowza Streaming Engine Manager管理界面上添加这些参数,你必须将它们添加在应用的自定义参数部分。下面是在Add Custom Property对话框中要输入的信息:
securityDebugLogRejections
Path |
Name |
Type |
Value |
Root/Application | securityDebugLogRejections | Boolean | true |
securityDebugLogDetails
Path |
Name |
Type |
Value |
Root/Application | securityDebugLogDetails | Boolean | true |
Hash值不匹配时拒绝Session会话连接
下面是因为客户端发来的Hash和Wowza自己计算的Hash不匹配时,Http session 被拒绝的日志例子:
注意: The securityDebugLogDetails 参数必须启用。
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 -
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 -
第一个红色高亮的log显示了用于计算Hash的字符串,这个字符串的各个组成部分是按阿拉伯字母顺序排列的,并且必须和客户端计算Hash时的字符串保持一致。
第二个红色高亮的log显示了Wowza生成的Hash和接收到的来自客户端的Hash,并提示它们两者并不匹配。
下面是Wowza 官方给出的一段PHP代码的例子,它展示了应该如何生成播放URL,如下:
<?php $clientIP = null; // provide client IP optionally $host = "[WOWZA-HOST]"; // your ip/host $url= "rtmp://".$host.":1935/"; // or "http://".$host.":1935/"; $stream = "vod/_definst_/mp4:sample.mp4"; // your stream $start = time(); $end = strtotime("+30 minutes"); $secret = "abcde"; $tokenName = "wowzatoken"; $hash = ""; if(is_null($clientIP)){ $hash = hash('sha384', $stream."?".$secret."&{$tokenName}endtime=".$end."&{$tokenName}starttime=".$start, true); // generate the hash string } else{ $hash = hash('sha384', $stream."?".$clientIP."&".$secret."&{$tokenName}endtime=".$end."&{$tokenName}starttime=".$start, true); // generate the hash string } $base64Hash = strtr(base64_encode($hash), '+/', '-_'); // $params = array("{$tokenName}starttime=".$start, "{$tokenName}endtime=".$end, "{$tokenName}hash=".$base64Hash); $params = array("{$tokenName}starttime=".$start, "{$tokenName}endtime=".$end, "{$tokenName}hash=".$base64Hash); if(!is_null($clientIP)){ $params[] = $clientIP; } sort($params); $playbackURL = $url.$stream."/playlist.m3u8?"; if(preg_match("/(rtmp)/",$url)){ $playbackURL = $url.$stream."?"; } foreach($params as $entry){ $playbackURL.= $entry."&"; } $playbackURL = preg_replace("/(\&)$/","", $playbackURL); // echo "$playbackURL"; // DEBUG - show fully formed URL ?>