Thursday, December 16, 2010

SmartFox Messaging explained

So it occurred to me that I may have run right past some important information without giving sufficient explanation. I'm going to take some time and explain how the messaging between Unity3D and SmartFox works.

First lets pull up the code from EncryptionProvider. Specifically the ClientPublicKeyToSFSObject function:

public ISFSObject ClientPublicKeyToSFSObject()
{
ISFSObject tr = new SFSObject();

tr.PutByteArray("mod", new ByteArray(ClientRSA.ExportParameters(false).Modulus));
tr.PutByteArray("exp", new ByteArray(ClientRSA.ExportParameters(false).Exponent));

ISFSObject data = new SFSObject();
data.PutSFSObject("key", tr);

return data;
}
The first thing we do is create an ISFSObject. This is the main class for transporting data between the server and client. Next you see we use PutByteArray. We use a Byte Array for for a very good reason. Our Modulus and Exponent are both of type byte[] which is a data type byte array. SFSObjects don't accept byte[] so we must wrap it into a ByteArray class, which in reality is what this already is. The first parameter, however is "mod". This parameter tells our object what to call this piece of data, it is our key. Next we see that we put in the exponent into the "exp" key. The last thing we do is wrap this entire object into another SFSObject. Now some of you may be saying "Why put it into another object when one will suffice?" The reason is pretty simple, if we add more data, like say the time our packet is sent, we want the data for the key to be distinct from the time our packet is sent.

Here is the final structure of key names for our object:
Data
  |
  +-- "key" (SFSObject)
    |
    +-- "mod" (ByteArray)
    |
    +-- "exp" (ByteArray)

This is important for our server side, we now know how the object is structured so we can dig into our object for all the pieces we need. Now lets look at the server side function that takes the data out.

    public void SetPublicKey(ISFSObject data) throws NoSuchAlgorithmException, InvalidKeySpecException {
                ISFSObject keyData = data.getSFSObject("key");
                RSAPublicKeySpec keySpec = new RSAPublicKeySpec(new BigInteger(keyData.getByteArray("mod")), new BigInteger(keyData.getByteArray("exp")));
                KeyFactory fact = KeyFactory.getInstance("RSA");
                pubKey = fact.generatePublic(keySpec);
    }

On the server side, you can see its almost an exact duplicate of the structure above. We first ask for an SFSObject with the string key of "key". We then look inside that object for 2 ByteArray's with keys of "mod" and "exp".

I'm sure many of you can guess that when we get to the next part, we will see the exact same thing. The server will package up the "mod" and "exp" of its public key, and put it in another SFSObject called "key" and send that back to the client.

No comments: