0

I'm working on an RSA sign() function for generating a signed URL for private streaming. I was testing on PHP code, but I want to re-code that in Flex. Here is the part of PHP code:

function getCannedPolicy($resource, $expires, $key, $privatekeyfile){
         $priv_key = file_get_contents($privatekeyfile);
         $pkeyid = openssl_get_privatekey($priv_key);
         $policy_str = '{"Statement":[{"Resource":"'.$resource.'","Condition":{"DateLessThan":{"AWS:EpochTime":'.$expires.'}}}]}';
         $policy_str = trim( preg_replace( '/\s+/', '', $policy_str ) );
         $res = openssl_sign($policy_str, $signature, $pkeyid, OPENSSL_ALGO_SHA1);
         $signature_base64 = (base64_encode($signature));
         $repl = array('+' => '-','=' => '_','/' => '~');
         $signature_base64 = strtr($signature_base64,$repl);
         $url = $resource . '?Expires='.$expires. '&Signature=' . $signature_base64 . '&Key-Pair-Id='. $key;

         return $url;
}

I write the same function in Flex. Here is the code:

private function getCannedPolicy(resource:String, expires:uint, key:String, privatekey:String):String{          
    var unsigned:String = '{"Statement":[{"Resource":"' +resource+ '","Condition":{"DateLessThan":{"AWS:EpochTime":' +expires+ '}}}]}';
    var signed:String = '';
    var signature:String = '';
    var regex:RegExp = /\s+/g;          
    unsigned = unsigned.replace(regex,'');
    var src:ByteArray = new ByteArray();            
    src.writeUTFBytes(unsigned);            
    var dst:ByteArray = new ByteArray();            
    var hash:SHA1 = new SHA1();
    src = hash.hash(src);                       
    var rsa:RSAKey = PEM.readRSAPrivateKey(privatekey);
    trace(rsa.dump());
    rsa.sign(src, dst, src.length);
    dst.position = 0;           
    signature = Base64.encodeByteArray(dst);                            
    signature = signature.split("+").join("-");
    signature = signature.split("=").join("_");
    signature = signature.split("\/").join("~");
    signed = resource+'?Expires=' +expires+ '&Signature=' +signature+ '&Key-Pair-Id=' +key; 

    return signed;
}

The outputs from the two functions (the PHP and the Flex) are the same format. But, when I'm using the signed URL from the Flex function, the stream not work.

The alternative I'm using for openssl_sign() php function is sign() function from as3crypto library. Maybe here is the problem? Maybe the encryption is different.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
ExtremeBt
  • 86
  • 9
  • If both implementations create the same results w/ the same data; then the issue is either an error in both functions, or not an issue with either function. when you say "the stream doesn't work" what do you mean? How are you using it in PHP? How are you using it in Flex? Do you get compile errors? or runtime errors? – JeffryHouser Jun 14 '11 at 14:56
  • The signed url contains parameter **expire** so if the date expires the url is not valid. I'm using JW player for streaming and I'm setting the signed url for the jw player via flashvars. For same format I mean the both functions return same parameter and signature with same length. When I put the signed url from flex function, JW player says: Stream not found! (this occured if date is expired or the signiture not match the policy. I think the second is) My question is: Can I use RSAKey.sign() from as3crypto instead of openssl_sign() php function?! Thanks! – ExtremeBt Jun 14 '11 at 15:05
  • Why would you opt to sign something client-side when it can (and should) be done server side? Public clients are insecure by nature, and there is hardly ever a case where putting security responsibilities on the client would make sense. The client should only be responsible for collecting and displaying data to and from the server (over SSL if security is an issue). This of course only applies to client-server architectures... – drkstr Jun 14 '11 at 15:38
  • The signing must be from client side. Actually this is desktop AIR application and must work with secure streaming. For this reason, the flex must generated the signed url, not php. – ExtremeBt Jun 14 '11 at 15:45
  • Ahh, well that would make sense then. For some reason I gathered from your question that it was a client-server app.... The sign function should work. What's up with the regex? Are you sure your input string is the exact same (careful of encoding) as the one being signed in php? – drkstr Jun 15 '11 at 02:29
  • Well the regex ignore the white spaces, tab spaces etc. if the string contains that. But, because the the policy not contain, the string is the same after and before the regex replacing. This is not the problem i guess. I think the problem is in _rsa.sign(src, dst, src.length);_ I don't know, is it that same _openssl_sign($policy_str, $signature, $pkeyid, OPENSSL_ALGO_SHA1);_? The both are rsa sign functions with sha1. I need help. Thanks for response! – ExtremeBt Jun 15 '11 at 08:28

1 Answers1

0

Unfortunately, the as3crypto's RSAKey.sign() is not the same function as php's openssl_sign(). Their outputs are different signatures. For that reason I decide to call remote php function to generated my signature. It works now!

ExtremeBt
  • 86
  • 9