Encryption

Photon enables you to encrypt messages between client and server on demand. The exception to this rule is authentication data, which is always sent encrypted.

Encryption is optional and sparingly used as it takes some performance. If a message can be shared with everyone in a room, it can probably be sent without encryption, too.

When used, encryption is always between a client and the server. Photon does not offer end-to-end encryption between clients.

Of course, you are in control.

Technical Details

When you use UDP or TCP as transport protocol, Photon clients will automatically exchange encryption keys with the server. This is done via Diffie-Hellman Key Exchange when a client connects.

The 160 bit key is then used for AES encryption on demand.

If an operation is sent encrypted, any data you send and all operation parameters are serialized and then encrypted. A lean header per message (length, etc.) remains unencrypted.

WSS Transport Protocol

If you use Unity's WebGL export to connect to Photon Cloud, the client will connect via Secure WebSockets. We recommend the use of WSS over WS when self hosting as well.

When the WSS Transport Protocol is used, all communication gets encrypted as you'd expect, including headers. In that case, Photon clients don't exchange encryption keys and don't apply AES on demand.

Encryption in PUN

In PUN, you can send RPCs and events with encryption on demand. The frequent and regular updates for networked objects, are not encrypted.

To call an RPC in a secure way, use RpcSecure() on any PhotonView.

PhotonNetwork.RaiseEvent() can be used to send custom events with or without encryption.

In both cases, the server will decrypt the message and re-encrypt it to send it the other players. A Server Plugin could make use of the data, read or change it.

Photon Tokens

Photon's Tokens are typically handled behind the scenes. It's not very visible in the client APIs but it makes sense to be aware of them.

Once a client is authenticated, the server will issue a Token, an encrypted summary of the client's authentication values to be used on other servers.

The Token is only used by the Photon servers and can't be read by the clients.

It's possible to "inject" some data into the token, to share it between servers (via the client). A Server Plugin may read this shared data from the Token.

Token Refresh

By default Photon tokens expire after 1 hour but in most cases they are refreshed for the client automatically. The refresh happens in two cases:

  1. when switching from Master Server to Game Server, if you create or join a room.
  2. as long as the client keeps raising events inside the room.

If a client stays inside a room for more than 1 hour without raising any event, the token will not be refreshed and expires. This will not disconnect the client from the Game Server but when it leaves the room, connection to the Master Server will fail and the client has to reconnect and authenticate again.

Encryption of Operations

In all C# APIs, we have a class called PhotonPeer. It is a lower level class which offers a method OpCustom(). This is the basis for all operation calls a client does and it has a parameter for encryption.

In PUN, the PhotonNetwork.NetworkingClient.LoadBalancingPeer is a PhotonPeer. In Realtime (a.k.a. LoadBalancing API), LoadBalancingClient.LoadBalancingPeer is a PhotonPeer.

Use OpCustom() with the encrypt-parameter set to true if needed.

Manually Establish Encryption

If you use the LoadBalancing API or PUN, you don't need to do this manually. Only if you start your client from scratch, you have to establish encryption after connecting.

In best case, call peer.EstablishEncryption() in OnStatusChanged like this:


    public void OnStatusChanged(StatusCode returnCode)
    {
        // handle returnCodes for connect, disconnect and errors (non-operations)
        switch (returnCode)
        {
            case StatusCode.Connect:
                this.peer.EstablishEncryption();
                // ...

The library takes care of sending and handling the required keys. When this finishes, the client library will call OnStatusChanged with either of these codes:


    public void OnStatusChanged(StatusCode returnCode)
    {
        // handle returnCodes for connect, disconnect and errors (non-operations)
        switch (returnCode)
        {
            // ...

            case StatusCode.EncryptionEstablished:
                // encryption is now available
                // this is used per operation call
                break;
            case StatusCode.EncryptionFailedToEstablish:
                // if this happens, get in contact with Exit Games
                break;

 To Document Top