0

I'm trying to pass a message from a Javascript Client to a PHP webserver. To add a layer of security I would like to sign the data object with an hash.

/* Generate signature of the data with the password */
that.signEnvelope = function(data,password)
{
      return CryptoJS.SHA256(JSON.stringify(data) + password).toString();
};

This quickly falls apart on the server. The JSON.stringify function does not generate a 1:1 matching string to json_encode on the server making it impossible to verify the hash.

protected function verifySignature($remoteSignature,$data,$privateKey)
{
    /* Combine json & key samen , then sha256 */
    $localSignature = hash('sha256',json_encode($data) . $privateKey);
    return ($localSignature === $remoteSignature);
}

Is there another algorithm that I can implement in both PHP and Javascript that will generate a hashable string ?

Conclusion

Allowing json_encode accross platforms was not a smart thing todo. There is no standard implementation.

Instead I now only allow arrays with string key/value pairs which are much easier to concat and verify.

6
  • Maybe show us the server-side? Commented Jul 9, 2012 at 14:26
  • 2
    Since all of this is very transparently happening on the client side, it's really not difficult to spoof data regardless of what or how you sign. In other words, not sure all this is really worth it. Commented Jul 9, 2012 at 14:31
  • @deceze Maybe the hash will be sent via a different, secure channel. Commented Jul 9, 2012 at 15:09
  • 1
    Apperently, hashing functions are no good for confirming message authenticity. Read Why you should never use hash functions for message authentication, tl;dr use HMAC. Commented Jul 9, 2012 at 15:13
  • @pixel That's cute and all, but the signature is still created by the client, in a very transparent way, right in front of the eyes of everyone who cares to look. Therefore it's easy for any attacker to repeat the same process, creating any signature he wants. How that's transferred to the server doesn't matter. Commented Jul 9, 2012 at 15:35

2 Answers 2

0

What you experiencing there is not limited to certain differing whitepace/linebreak-characters. It is also worth mentioning, that different charsets can lead to different output. A ISO8859-15 Euro-Sign is 1 byte long, a UTF8 Euro-Sign is 3 bytes long and there is always the chance to encode a Char with the \u####-declaration. JSON-libs is not intended to produce comparable strings over different plattforms.

If you still want to utilize JSON, you have to either use libs, that behave identical on all input, or build your own. JSON is easy to generate by hand.

1
  • I realized that I was too ambitious in allowing JSON encoded data to be send. I have reduced the spec to allow only basic string key/value pairs which can be more easily added together and validated on both sides. Commented Jul 10, 2012 at 7:25
0

You could use the JS version of json_encode to get a 1:1 match:

http://phpjs.org/functions/json_encode

1
  • That is interesting, I will try this. Commented Jul 9, 2012 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.