Secure streaming to the iPhone and iPod Touch (AES-128, internal method)

Eric,

From your description, with encryption in place, it sounds like your stress test is breaking the system, but I don’t think it is a valid load test. Wowza has a load test tool that simulates many connection for a live or vod application. It only does rtmp streams, but you can extrapolate. You can get the load test tool by sending request to test@wowza.com

Richard

Eric,

It’s just not a valid load test tool. You are only proving that you can confuse Wowza and the phone, which is streaming from a high-latency playlist of encrypted chunks grouped by sessionID.

You can get the the load test tool by sending request to test@wowza.com. The load test tool only does vod and live rtmp streaming, but it gives you an idea of what your server can handle, and you can extrapolate.

Richard

Eric,

The way to test encryption is download one of the .ts chunks from the playlist and try to play it in VLC. It should not be playable in VLC if encryption is working correctly.

The way to download one of the .ts chunks is:

  • Enter playlist.m3u8 URL in a browser, for example:

    http://localhost:1935/vod/mp4:sample.mp4/playlist.m3u8
    
    

    A playlist.m3u8 file is downloaded to your computer

  • Open the playlist.m3u8 file that is download in a text editor, then copy the the URL you see (including the wowzasesssionid) to a browser. It will look something like this:

    http://localhost:1935/vod/mp4:sample.mp4/playlist.m3u8?wowzasessionid=1776170579
    
    

    Another playlist.m3u8 file is downloaded to your computer

  • Open the new playlist.m3u8 file, then copy one of .ts URLs and append, something like this:

    http://localhost:1935/vod/mp4:sample.mp4/media_4.ts?wowzasessionid=1776170579
    
    

    Richard

You have to build the module and add Module and Properties to Application.xml.

https://www.wowza.com/docs/how-to-use-the-internal-method-of-aes-128-encryption-to-secure-live-or-vod-streams-sent-to-apple-ios-devices-moduleencryptionhandlercupertinostreaming)

Richard

Eric,

In origin/edge (liverepeater), this encryption module is setup on the origin, so the stream from the origin to the edge, then from edge to client is encrypted. Note the properties at the bottom of the post for configuring an edge application.

RTSP and RTMP are handled separately in origin to edge connection, that is how it works.

Richard

Hi All,

I need to add secure live streaming in iphone app using http streaming protocol

I have read this tutorial but i m totally confused

tell me if i need to use this

http://[localhost}:1935/[App_name]/[stream_name]/playlist.m3u8

how can i use key here???

Also , how can these methods be called?

public void onHTTPCupertinoEncryptionKeyRequest(HTTPStreamerSessionCupertino httpCupertinoStreamingSession, IHTTPRequest req, IHTTPResponse resp)

{

boolean isGood = true;

String ipAddress = httpCupertinoStreamingSession.getIpAddress();

String queryStr = req.getQueryString();

String referrer = httpCupertinoStreamingSession.getReferrer();

String cookieStr = httpCupertinoStreamingSession.getCookieStr();

String userAgent = httpCupertinoStreamingSession.getUserAgent();

String sessionId = httpCupertinoStreamingSession.getSessionId();

IApplicationInstance appInstance = httpCupertinoStreamingSession.getAppInstance();

String streamName = httpCupertinoStreamingSession.getStreamName();

// reject encryption key requests that are not delivered over SSL

//if (!req.isSecure())

// isGood = false;

getLogger().info(“ModuleEncryptionHandlerCupertinoStreaming.onHTTPCupertinoEncryptionKeyRequest[”+appInstance.getContextStr()+"/"+httpCupertinoStreamingSession.getStreamName()+"]: accept:"+isGood);

if (!isGood)

httpCupertinoStreamingSession.rejectSession();

}

public void onHTTPCupertinoEncryptionKeyCreateLive(IApplicationInstance appInstance, String streamName, byte[] encKey)

{

String mySharedSecret = appInstance.getProperties().getPropertyStr(“cupertinoEncryptionSharedSecret”, “”);

String hashStr = mySharedSecret+":"+appInstance.getApplication().getName()+":"+appInstance.getName()+":"+streamName;

byte[] tmpBytes = MD5DigestUtils.generateHashBytes(hashStr);

if (tmpBytes != null)

System.arraycopy(tmpBytes, 0, encKey, 0, encKey.length);

getLogger().info(“ModuleEncryptionHandlerCupertinoStreaming.onHTTPCupertinoEncryptionKeyCreateLive[”+appInstance.getContextStr()+"/"+streamName+"]: *"+BufferUtils.encodeHexString(encKey).substring(28));

}

public void onHTTPCupertinoEncryptionKeyCreateVOD(HTTPStreamerSessionCupertino httpCupertinoStreamingSession, byte[] encKey)

{

String ipAddress = httpCupertinoStreamingSession.getIpAddress();

String queryStr = httpCupertinoStreamingSession.getQueryStr();

String referrer = httpCupertinoStreamingSession.getReferrer();

String cookieStr = httpCupertinoStreamingSession.getCookieStr();

String userAgent = httpCupertinoStreamingSession.getUserAgent();

IApplicationInstance appInstance = httpCupertinoStreamingSession.getAppInstance();

String streamName = httpCupertinoStreamingSession.getStreamName();

String sessionId = httpCupertinoStreamingSession.getSessionId();

String mySharedSecret = appInstance.getProperties().getPropertyStr(“cupertinoEncryptionSharedSecret”, “”);

String hashStr = mySharedSecret+":"+sessionId+":"+appInstance.getApplication().getName()+":"+appInstance.getName()+":"+httpCupertinoStreamingSession.getStreamName();

byte[] tmpBytes = MD5DigestUtils.generateHashBytes(hashStr);

if (tmpBytes != null)

System.arraycopy(tmpBytes, 0, encKey, 0, encKey.length);

getLogger().info(“ModuleEncryptionHandlerCupertinoStreaming.onHTTPCupertinoEncryptionKeyCreateVOD[”+appInstance.getContextStr()+"/"+httpCupertinoStreamingSession.getStreamName()+"]: *"+BufferUtils.encodeHexString(encKey).substring(28));

}

Thanks

Plz it’s urgent

Hi Richard,

I have used RTMPAuthentication for publishing from FMLE encoder and used SecureToken for playback by flash player

Now i have following setup to conf

ModuleRTMPAuthenticate

ModuleRTMPAuthenticate

com.wowza.wms.plugin.security.ModuleRTMPAuthenticate

secureTokenSharedSecret

mypassword

in FLASH AS

if (infoObject.info.code == “NetConnection.Connect.Success”)

{

if (infoObject.info.secureToken != null)

nc.call(“secureTokenResponse”, null, TEA.decrypt(infoObject.info.secureToken, “mypassword”));

}

Now, the problem is that publishing from FMLE and playback by flash player works fine

BUT

if I need to publish from flash player , it rejects the stream saying stream not authorized to publish

I need to Support FMLE(publish)/Flash player(PLay) and flash player(publish)/Flash player(PLay) by same wowza application

also if i add securetoken module to conf it does not allow to publish FMLE

plz help it’s really urgent

Thanks alot

Hi Richard,

I have tried both approaches but no result:(

still

NetStream.Publish.Failed (Not authorized to publish)

isnt there any other way by which i can support both publish/play by flashplayer and publish(FMLE)/play(flash player)

thanks

I am using this method but i have a question about cupertinoEncryptionBaseURL that i can’t seem to find the answer to,

I have 2 wowza boxes running on ec2 and I am using a zip config package to start the boxes. how am i suppose to be setting this URL? I am trying the following, but it does not work :

cupertinoEncryptionBaseURL

http://${com.wowza.amazonaws.ec2.AWSEC2_METADATA_PUBLIC_HOSTNAME}:1935

It results in a url that looks like http://${com.wowza.amazonaws.ec2.AWSEC2_METADATA_PUBLIC_HOSTNAME}:1935 and not th ec2 hostname. So i am doing something wrong here…

My other question is if i make a DNS alias to something like wowza.myhost.com and then used that, does it matter which host gets the connection for cupertinoEncryptionBaseURL or do i have to ensure that the wowza box handling the request is the one to hand out the encryption?

What is the correct way to do this when launching more than one box or launching a wowza box without knowing what it’s ip will be before it starts?

When i configure the SSL port i am having problems…by using the port 1953 i am able to see the live stream on an iPad…I am guessing that i am probably doing something wrong in configuring the SSL port…When i checked the log i observed that there is no log of “onHTTPCupertinoEncryptionKeyRequest” although i can see logs of “onHTTPCupertinoEncryptionKeyCreateLive”…

The basic steps i followed while configuring the SSL port are:

  1. i ran the keytool from the command prompt by changing to the jdk bin directory

  2. i moved the cert file to the [install]/conf folder of wowza

  3. i uncommented teh ssl port and made changes to it as per the user guide document -

(put keystorepath and keystorepassword in the VHost)

  1. i built the java code again in the Wowza IDE by uncommenting the following:

//if (!req.isSecure())

// isGood = false;

5)i changed the 1935 port to 443 in the application conf file i.e.cupertinoEncryptionBaseURL value

Please let me know if i am doing something wrong. I do not see any error logs on Wowza and it spits out chunks normally…but i do not see any video on my iPad…

Thank you sir. I will try doing it with a certificate from a certificate authority and see if it works without any problems.

I am trying to play the live stream with AES 128 bit encryption (internal method) on the iphone. I compiled the program and included the jar file in the library. But when i run the stream, it is getting into the

onHTTPCupertinoEncryptionKeyCreateLive method

and creating the key but it wouldn’t show any traces of getting into the

onHTTPCupertinoEncryptionKeyRequest method

When i try to access the live stream i get the message “You are not authorized to open the file” in the iphone/ipad.

Please let me know what the problem is.

Can someone please help me out with this?..i’ve been trying since 2 days and i’ve also been waiting for a reply since early morning…i would really appreciate it…

I’ve been able to accomplish this earlier, but now somehow it doesn’t work…I have authentication set to none in the play method…is there anything else that we are supposed to do apart from the steps given in the beginning of this post?

I’m still getting the same message saying “You are not authorized to open this file”.

Waiting for a reply,

Thanks,

Nish.

Richard,

Thank you for the reply…i tried setting up the whole application again from scratch with a new Application.xml…still gives me the same problem…

Can you tell me what prompts the Wowza Server to look into the method -

onHTTPCupertinoEncryptionKeyRequest

The problem is that the key is being generated but the server isn’t getting into the above method to request for the generated key…hence i am getting rejected…

I would try some other things if you could tell me what prompts the server to request for the key…Do i need some other modules for that?

Thanks a ton,

Nish

Richard,

Here is my Application.xml

true

live

${com.wowza.wms.context.VHostConfigHom e}/content

${com.wowza.wms.context.VHostConfigHome}/keys

cupertinostreamingpacketize r,smoothstreamingpacketizer

cupertinostreaming,smoothstreamin g

-1

*

*

*

*

digest

none

senderreport

12000

75

90000

0

0.0.0.0

127.0.0.1

*

base

Base

com.wowza.wms.module.ModuleCore

properties

Properties

com.wowza.wms.module.ModuleProperties

logging

Client Logging

com.wowza.wms.module.ModuleClientLogging

flvplayback

FLVPlayback

com.wowza.wms.module.ModuleFLVPlayback

ModuleEncryptionHandlerCupertinoStreaming

ModuleEncryptionHandlerCupertinoStrea ming

com.wowza.wms.example.module.ModuleEncrypti onHandlerCupertinoStreaming

cupertinoEncryptionBaseURL

http://172.28.2.98:1935

cupertinoEncryptionSharedSecret

enckeysharedsecret

cupertinoEncryptionLiveRepeaterSharedSecre t

mysharedsecret

Thanks for taking a look into this.

PS: I did refer to the other post…I checked my application.xml i did not commit that same mistake. There are some unwanted spaces in the Application.xml but that is only due to pasting it here, not in the original file. Thanks.

Charlie,

Sir, i set the application level properties even on liveedge application ( the one i am using is live) … even after this i am getting teh same message which says

“You are not authorized to open this file” … The problem is that it is not getting into the onHTTPCupertinoEncryptionKeyRequest method…i can see the traces of the keys being generated (onHTTPCupertinoEncryptionKeyCreateLive method) … this doesn’t make too much sense because i am assuming that the key should be requested automatically…

:confused:

Nish.

Charlie,

I sent the file to support@wowza.com through ‘yousendit’ with a reference to this thread. Thanks a ton for looking into this.

Here is the link:

http://www.yousendit.com/download/UFVyTmZldzh0NjljR0E9PQ

Regards,

Nish.

Richard/Charlie,

After days of debugging, i finally identified what the problem is. It is actually very weird.

The stream files i am creating have spaces in the filenames. This is working well in any other case(direct streaming without encryption) but when i apply AES 128 bit encryption(internally), it does not work in cases where there are spaces in the stream file name.

Is there a solution to this? I really do need spaces in the .stream filenames and i also need the AES 128 bit encryption.

Regards,

Nish.

Charlie,

Thanks for the reply. I was working on it in the meanwhile and i solved it programmatically in my application by using a work around.

Thanks anyway! :slight_smile:

Hi all,

I was just playing around with this and it seems (for me) to break when used in an origin-edge configuration.

It works when I connect to the origin but not to edge. This is the log from the origin when the edge is trying to connect:

ERROR server comment - HTTPStreamerAdapterCupertinoStreaming.onEncKey: java.lang.NullPointerException
java.lang.NullPointerException
	at com.wowza.wms.httpstreamer.cupertinostreaming.httpstreamer.HTTPStreamerAdapterCupertinoStreamer.onEncKey(Unknown Source)
	at com.wowza.wms.httpstreamer.cupertinostreaming.httpstreamer.HTTPStreamerAdapterCupertinoStreamer.serviceMsg(Unknown Source)
	at com.wowza.wms.httpstreamer.cupertinostreaming.httpstreamer.HTTPStreamerAdapterCupertinoStreamer.service(Unknown Source)
	at com.wowza.wms.server.ServerHandler.serviceRequest(Unknown Source)
	at com.wowza.wms.server.ServerHandler.handleMessageReceived(Unknown Source)
	at com.wowza.wms.server.ServerHandler.messageReceived(Unknown Source)
	at com.wowza.wms.server.ServerHandlerThreaded.messageReceived(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain$2.messageReceived(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$900(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(Unknown Source)
	at org.apache.mina.filter.codec.support.SimpleProtocolDecoderOutput.flush(Unknown Source)
	at org.apache.mina.filter.codec.ProtocolCodecFilter.messageReceived(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain.access$900(Unknown Source)
	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(Unknown Source)
	at org.apache.mina.filter.executor.ExecutorFilter.processEvent(Unknown Source)
	at org.apache.mina.filter.executor.ExecutorFilter$ProcessEventsRunnable.run(Unknown Source)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:637)

This results in a “File could not be found” on iDevices.

The last line in the edge log is about the streaming being beyond iPhone reccomendations.