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 256 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.

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.

C# SDKs

In this page we are referring to C# client SDKs only. The same features should be available in other SDKs.

Encryption of Operations

In all C# client SDKs, we have a class called PhotonPeer. To send an operation encrypted, call PhotonPeer.SendOperation with the sendOptions parameter that has sendOptions.Encrypt = true.

But usually you do not need to use that class or call that method yourself. It is done internally in a lower level. In the C# APIs we provide high level classes for Photon networking clients.

  • In PUN1, the PhotonNetwork.networkingPeer is a PhotonPeer.
  • In Photon Realtime, LoadBalancingClient.LoadBalancingPeer is a PhotonPeer.
  • In Photon Voice, LoadBalancingTransport extends LoadBalancingClient.
  • In PUN2, the PhotonNetwork.NetworkingClient is a LoadBalancingClient.
  • In Photon Chat, ChatClient.chatPeer is a PhotonPeer.

Manually Establish Encryption

In our client SDKs, you don't need to do this manually. Only if you start your client from scratch (reference only the library), you have to establish encryption after connecting.

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

C#

    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:

C#

    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;
Back to top