ATTENTION: You are viewing a page formatted for mobile devices; to view the full web page, click HERE.

Other Software > Developer's Corner

Decrypting a key on a time limit, but without knowing the time

(1/1)

mediaguycouk:
Hi there. I'm stumped on something and would like some ideas passed around even if you don't know how to technically achieve what I'm asking for.

Before I start with the problem I'm using
Wowza - Flash streaming server
Flash CS4
JW Media Player (Longtail media player) - Under licence editing the source code.

I have videos on a streaming server that require authentication. Users log in with their university username and password and a $_SESSION variable is logged to show the user is logged in.

In the past I have totally hacked at the source code of JW Media Player to ensure that the video doesn't play without checking the session is logged in. A written application in Flash Media Server 2 also checked this information.

For this new version I would like both Wowza and JW Media player to be as 'vanilla' as possible. The reason for this is Wowza and JW Media Player both have built in authentication.

Wowza uses a secure token before an application (a whole folder of videos) can be played. The trouble is the token doesn't change and if I hard code the token into the flash player someone would only have to download the movie player to be able to play all moves.

What I would prefer to do is to pass some code to the flash player that makes it create the key, however I want it to be useless after it is used.

Before I would use the (sudo) code of

Decrypt (jr;;p, 13/3/09)

Function decrypt(input, date) {
 if (date < today) {
  exit("password can only be decrypted on the date it is created");
 } else {
  return decryptcode(input); // return token to the flash code and not to the user
 }
}

However if I'm doing the decryption inside the flash player it is using the client for its information. The client clock might be incorrect or they might just change it.

What would be best is if the web server were to pass the token at the beginning, but that would just involve the user right clicking and viewing source, which is even worse.

Any ideas or was that a really bad explanation?

Deozaan:
Can't you just get the flash player to communicate with an online server and let the server handle all of that stuff?

Ehtyar:
I'm afraid after reading it through a few times I still get lost in your explanation. My only recommendation is that all validation go server side, but I understand that that's not always an option.

Ehtyar.

f0dder:
As Ehtyar said, handle authentication stuff server-side. If a user's session/whatever has expired, simply deny access to the media files - presto, problem, solved.

mediaguycouk:
I was worried it might be that way.

What I really wanted was to not have to re-write a whole application when a token based system was already built into the serverside code.

Basically I would have to re-write this actionscript into Java (which I don't know)

Spoiler
--- Code: ActionScript ---// Written by Graham Robinson - [email protected]("build 0169"); // To make life easier all applications of main.asc are the same. The secuirty checks that happen between// Internal, ISS authenticated, etc happen by what is defined on the next line load("appsettings.asc"); // IP CHECK (our website here. No http:// or trailing /)var VALID_REFERRER = "xxx.xxx.xxx.ac.uk";  // Bypass referral// If you are testing on your local computer you can bypass the reffer check// You will still need to pass security to the host unless you use the public profile //var BYPASS_REFERRER = "yes"; // Comment out as necessaryvar BYPASS_REFERRER = "no"; // << ALWAYS USE THIS FOR A LIVE SYSTEM // IP CHECK (power referrer to allow server to connect to itself and for streaming)var POWER_REFERRER = "rtmp://xxx.xxx.ac.uk/"+application.name ; // Note to self. When you get hold of flash media encoder 2, you need to see how it connects// to the server as the unique key and referrer checks will fail when using the laptop.// The laptop itself may need a static address just to allow entry via IP. function checkInternal(internalTime, internalTimeHash, pClient) {        var internal_lv = new LoadVars();        internal_lv.load("http://127.0.0.1/flashserver_secure/serversecuritycheck_internal.php?time="+internalTime+"&hash="+internalTimeHash+"&nothingelse");        internal_lv.onLoad = function( success )        {                //trace("Internal check: "+internal_lv.passed);                if (internal_lv.passed == "yes") {                        //trace("Accepting connection from internal function")                        application.acceptConnection(pClient);                } else {                        //trace("Rejecting connection from internal function")                        application.rejectConnection(pClient);                }        }       }function checkISS(issTime, issTimeHash, pClient) {        var iss_lv = new LoadVars();        iss_lv.load("http://127.0.0.1/flashserver_secure/serversecuritycheck_iss.php?time="+issTime+"&hash="+issTimeHash+"&nothingelse");        iss_lv.onLoad = function( success )        {                //trace("ISS Check: "+iss_lv.passed);                if (iss_lv.passed == "yes") {                        //trace("Accepting connection from iss function")                        application.acceptConnection(pClient);                } else {                        //trace("Rejecting connection from iss function")                        application.rejectConnection(pClient);                }        }} // Some code to work with published live servers // Define the variable we will share to tell when the stream has startedisStreaming = new Object(); isStreaming.connected = "no";isStreaming.streaming = "no";isStreaming.clientID = ""; Client.prototype.FCPublish = function(streamname) {        //this.call("onFCPublish", null, {code:"NetStream.Publish.Start", description:"name"});        //trace("I'm funning in a FCPublish function");        isStreaming.streaming = "yes";} Client.prototype.FCUnpublish = function(streamname) {// perform your clean up        //this.call("onFCUnpublish", null, {code:"NetStream.Unpublish.Success", description:"name"});        //trace("I'm funning in a FCUnpublish function");        isStreaming.streaming = "no";} Client.prototype.releaseStream = function(streamname) {        // Nothing really needs to go here as FCPublish does all the work        // However the function needs to be defined to remove the 'unknown method' error        //trace("I'm funning in a releaseStream function");} // Ripping check// this will store references of all clients, and ensure there are no replays clientKeyList = new Object();  application.onConnect = function(pClient, uniqueKey, applicationName, internalTime, internalTimeHash, issTime, issTimeHash) {         //trace("SECURITY_METHOD = "+SECURITY_METHOD);        if (pClient.referrer == POWER_REFERRER && LIVE == "yes") {                this.acceptConnection(pClient);                 trace("Power referrer conneted: " + pClient.ip);                isStreaming.connected = "yes";                isStreaming.clientID = pClient;        } else {                //pClient.writeAccess = ""; // prevents creating shared object or live streams.                 // Only allow flash movies to play when they are on our streaming server                // Note, this does not stop people from putting our .swf file onto their servers                if (pClient.referrer.split("/")[2] == VALID_REFERRER || BYPASS_REFERRER == "yes") {                         //trace("Accepted IP: "+pClient.referrer);                        if (uniqueKey != undefined) { // make sure there is always a uniqueKey                                 if ( clientKeyList[uniqueKey] == undefined ) {                                         // This client has never connected -- allow the connection                                         pClient.uniqueKey   = uniqueKey;                                         clientKeyList[uniqueKey]  = pClient;                                          if (isStreaming.connected == "yes" || LIVE == "no") {                                                if (isStreaming.streaming == "yes" || LIVE == "no") {                                                         // Run the correct security check based on the security type                                                        if (SECURITY_METHOD == "internal") {                                                                //trace("running checkInternal");                                                                checkInternal(internalTime, internalTimeHash, pClient);                                                        } else if (SECURITY_METHOD == "iss") {                                                                //trace("running checkISS");                                                                checkISS(issTime, issTimeHash, pClient);                                                        } else {                                                                //trace("Accepted due to security being none");                                                                this.acceptConnection(pClient);                                                        }                                                } else {                                                        //trace("Rejected: Broadcast is connected but not streaming");                                                         this.rejectConnection(pClient, {msg:"notStreaming"});                                                 }                                        } else {                                                //trace("Rejected: Broadcast is not connected");                                                 this.rejectConnection(pClient, {msg:"notConnected"});                                         }                                } else {                                         trace("Rejected UniqueID");                                         this.rejectConnection(pClient);                            }                         } else {                                   trace("Rejected No UniqueID");                                   this.rejectConnection(pClient);                         }                } else {                         // If the .swf wasn't on our server, reject and trace the referrer                        this.rejectConnection(pClient, {msg:"Bad referrer"}) ;                        //this.acceptConnection(pClient); // ONLY FOR TESTING PURPOSES                        trace("Rejected IP: "+pClient.referrer);                }         }} application.onDisconnect = function(pClient){        if (pClient == isStreaming.clientID) {                isStreaming.connected = "no";                isStreaming.clientID = "";                trace("Power referrer disconnected");        }        //clean up the keys         delete clientKeyList[pClient.uniqueKey];         //trace("Client disconnected");}

Navigation

[0] Message Index

Go to full version