End-to-End Encryption
Use the End-to-End Encryption API to encrypt media being sent through a media server from your application.
Important: In OpenTok.js 2.27.0, end-to-end encryption will not work with clients using earlier version of OpenTok.js. When you upgrade your app to use OpenTok.js 2.27.0+, make sure all clients are using OpenTok.js 2.27.0+ if the app uses end-to-end encryption.
Overview
End-to-end encryption (or E2EE) allows application developers to encrypt media in routed sessions from client to client. For relayed sessions, media is already encrypted client-to-client, through WebRTC protocols. This feature adds an encryption layer by encrypting the media payload at the client so that it will remain encrypted through the Media Router that routes media to other clients (in routed sessions). You enable end-to-end encryption when you create a session.
End-to-end encryption is supported in web apps on Chromium-based browsers (Chrome,Opera, and Edge).
You set the encryption secret in a web application using OpenTok.js. You must set encryption secrets in the web client when you initialize a session, and you can change encryption secrets on the fly once the session has connected. The encryption secret is a non-empty string. All users must use the same secret to receive intelligible media. The encryption secret is key material for generating a cryptographic key that is used to encrypt and decrypt media. Specifically, the encryption secret generates an AES-256 encryption key using an AES-CTR algorithm with a 256-bit key.
Please note that the Media Router does not have access to unencrypted media when using end-to-end encryption.
So, features that require media decoding --- such as archiving, live streaming broadcasts, experience composer, audio connector, and SIP interconnect --- are unsupported in end-to-end encrypted sessions.
Adding end-to-end encryption for your account
End-to-end encryption is available as an add-on feature. You can enable it on your Video account page.
Enabling encryption using the REST API
You enable end-to-end encryption when you create a session using the REST API. Set the e2ee property to true.
See session creation.
Note: Before enabling end-to-end encryption for a session, you must enable it for your Video account.
The following Node.js example creates an end-to-end encryption enabled session:
Implementations
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API). To have a React Native client join an end-to-end encrypted session, set the encryptionSecret prop of the OTSession component:
A valid secret is a string between 8 and 256 characters.
You can change the secret by setting the encryptionSecret prop to a property of the React state and changing its value:
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
The OTSubscriber error() event handler callback is invoked when the subscriber is unable to decode a stream's media due to a mismatched (or unset) encryption secret:
The OTSession error() event handler callback is invoked if the client tries to connect to an end-to-end encrypted session that was initialized with an invalid encryption secret (or without specifying an encryption secret). A valid secret is a string between 8 and 256 characters. For the best user experience, the application should catch an invalid user supplied secret before setting the OTSession encryptionSecret prop. In the following example, a session is initialized with an empty (and thus invalid) secret, which causes an error when attempting to connect:
Note: In OpenTok.js 2.27.0, end-to-end encryption will not work with clients using an earlier version of OpenTok.js. When you upgrade your app to use OpenTok.js 2.27.0+, make sure all clients are using OpenTok.js 2.27.0+ if the app uses end-to-end encryption.
Initializing a session with a secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API). To have a web client join an end-to-end encrypted session, specify an encryption secret when calling the OT.initSession() method:
A valid secret is a string between 8 and 256 characters. The secret can later be changed with the Session.setEncryptionSecret() method (see Changing the secret, below).
Checking whether the browser supports end-to-end encryption
Use the OT.hasEndToEndEncryptionSupport() method to check if the client's browser supports end-to-end encryption:
Currently, end-to-end encryption is only supported in Chrome (desktop and mobile), Opera, and Edge. It is not supported in Firefox or Safari. Also, end-to-end encryption is only supported when using the VP8 codec (the default).
Changing the secret
You can change the secret using the Session.setEncryptionSecret() method after the session has connected:
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
A Subscriber object dispatches an encryptionSecretMismatch event when the subscriber is unable to decode a stream's media. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video bug:
Also, it is important to communicate to users that encryption has been successfully enabled. A Subscriber object dispatches an encryptionSecretMatch event when the subscriber is able to decode the stream's media after a previous mismatch.
Also, it is important to communicate to users that encryption has been successfully enabled. A Subscriber object dispatches an encryptionSecretMatch event when the subscriber is able to decode the stream's media after a previous mismatch.
The Session.connect() callback is invoked with an error if the client tries to connect to an end-to-end encrypted session that was initialized with an invalid encryption secret. A valid secret is a string between 8 and 256 characters. For the best user experience, the application should catch an invalid user supplied secret before calling the OT.initSession() method. In the following example, a session is initialized with an empty (and thus invalid) secret, which causes an error when attempting to connect:
The Session.connect() callback is invoked with an error if a user attempts to connect to an end-to-end encrypted session in a browser that does not support end-to-end encryption.
If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, the Session.publish() callback is invoked with an error. For the best user experience, the application should validate a user-supplied secret before calling the session.publish() method:
If a user tries to subscribe in an end-to-end encrypted session without having specified an encryption secret, the Session.subscribe() callback is invoked with an error. For the best user experience, the application should validate a user-supplied secret before calling the Session.subscribe() method:
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API).
Before the client publishes or subscribes, call the Session.setEncryptionSecret() method:
A valid secret is a string between 8 and 256 characters. You can change the secret by calling the Session.setEncryptionSecret() function again.
Setting an invalid secret will result in an InvalidEncryptionSecret error.
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
If a client tries to connect to an end-to-end encrypted session without setting an encryption secret, the SessionListener.onError() event handler is called with an error code set to ErrorCode.EncryptionSecretMissing:
session.connect(token); If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, calling the Session.publish() method results in the PublisherListener.onError() event handler being called with an error that has the code set to ErrorCode.EncryptionSecretMissing. For the best user experience, the application should validate a user-supplied secret before calling the Session.publish() method:
If a subscriber is unable to decode a stream's media due to an incorrect encryption secret, the SubscriberListener.onError() event handler is called with an error that has the code set to ErrorCode.EncryptionSecretMismatch. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video issue:
session.subscribe(subscriber); If the application tries to subscribe without setting an encryption secret, the Subscriber.onError() event handler is called with an error that has the code set to ErrorCode.EncryptionSecretMissing.
If a subscriber encounters an internal error while decrypting a packet, the Subscriber.onError() event handler is called with an error that has the code set to ErrorCode.DecryptionInternalError.
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API).
Before the client publishes or subscribes, call the [OTSession setEncryptionSecret:error:] method:
A valid secret is a string between 8 and 256 characters. You can change the secret by calling the Session.setEncryptionSecret() method again.
Setting an invalid secret will result in an InvalidEncryptionSecret error.
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
If the client tries to connect to an end-to-end encrypted session and does not set the encryption secret before connecting, an error with the code set to EncryptionSecretMissing:
If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, calling the [OTSession publish:error:] method results in an error that has the code set to OTPublisherEncryptionSecretMissing. For the best user experience, the application should validate a user-supplied secret before publishing:
If a subscriber is unable to decode a stream's media due to an incorrect encryption secret, the [OTSubscriberKitDelegate subscriber:didFailWithError:] message is sent with an error that has the code set to ErrorCode.EncryptionSecretMismatch. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video issue:
If a subscriber encounters an internal error while decrypting a packet, the [OTSubscriberKitDelegate subscriber:didFailWithError:] message is sent with an error that has the code set to OTSubscriberDecryptionInternalError.
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API).
Before the client publishes or subscribes, call the [OTSession setEncryptionSecret:error:] method:
A valid secret is a string between 8 and 256 characters. You can change the secret by calling the Session.setEncryptionSecret() method again.
Setting an invalid secret will result in an InvalidEncryptionSecret error.
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
If the client tries to connect to an end-to-end encrypted session and does not set the encryption secret before connecting, an error with the code set to EncryptionSecretMissing:
If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, calling the [OTSession publish:error:] method results in an error that has the code set to OTPublisherEncryptionSecretMissing. For the best user experience, the application should validate a user-supplied secret before publishing:
If a subscriber is unable to decode a stream's media due to an incorrect encryption secret, the [OTSubscriberKitDelegate subscriber:didFailWithError:] message is sent with an error that has the code set to ErrorCode.EncryptionSecretMismatch. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video issue:
If a subscriber encounters an internal error while decrypting a packet, the [OTSubscriberKitDelegate subscriber:didFailWithError:] message is sent with an error that has the code set to OTSubscriberDecryptionInternalError.
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API).
Before the client publishes or subscribes, call the Session.SetEncryptionSecret() method:
A valid secret is a string between 8 and 256 characters. You can change the secret by calling the Session.SetEncryptionSecret() method again.
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
If a client tries to connect to an end-to-end encrypted session without setting an encryption secret, the Session.Error event is sent with an error code set to ErrorCode.EncryptionSecretMissing:
If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, calling the Session.Publish() function results in the Publisher.Error event being sent with an error that has the code set to ErrorCode.EncryptionInternalError. For the best user experience, the application should validate a user-supplied secret before calling the Session.Publish() method:
If a subscriber is unable to decode a stream's media due to an incorrect encryption secret, the Subscriber.Error event is sent with an error that has the code set to ErrorCode.EncryptionSecretMismatch. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video issue:
If a subscriber encounters an internal error while decrypting a packet, the Subscriber.Error event is sent with an error that has the code set to ErrorCode.DecryptionInternalError.
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the [REST API](/video/guides/end-to-end-encryption/overview#enabling-encryption-using-the-rest-api)).Before the client publishes or subscribes, call the otc_session_set_encryption_secret() function:
A valid secret is a string between 8 and 256 characters. You can change the secret by calling the otc_session_set_encryption_secret() function again.
Passing an invalid secret will result in an OTC_SESSION_INVALID_ENCRYPTION_SECRET error.
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.The new error code is OTC_SESSION_INVALID_ENCRYPTION_SECRET and will be returned as the result code of the set_encryption_secret method, not in the on_error callback.
If a client tries to set an invalid encryption secret for a session, the otc_session_callbacks.on_error() returns an error code set to OTC_SESSION_INVALID_ENCRYPTION_SECRET. In the following example, a session is initialized with an empty (and thus invalid) encryption secret:
If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, calling the otc_session_publish() function results in the otc_publisher_callbacks.on_error() fuction being called with an error that has the code set to OTC_SESSION_ENCRYPTION_SECRET_MISSING. For the best user experience, the application should validate a user-supplied secret before calling the otc_session_publish() function:
If a subscriber is unable to decode a stream's media due to an incorrect encryption secret, the subscriber_callbacks.on_error() function is called with an error that has the code set to OTC_SUBSCRIBER_ENCRYPTION_SECRET_MISMATCH. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video issue:
If a subscriber encounters an internal error while decrypting a packet, the subscriber_callbacks.on_error() function is called with an error that has the code set to OTC_SUBSCRIBER_DECRYPTION_INTERNAL_ERROR.
Setting the encryption secret
End-to-end encrypted sessions are created using server APIs (see Enabling encryption using the REST API).
Before the client publishes or subscribes, call the otc_session_set_encryption_secret() method:
A valid secret is a string between 8 and 256 characters. You can change the secret by calling the otc_session_set_encryption_secret() function again.
Setting an invalid secret will result in an OTC_SESSION_INVALID_ENCRYPTION_SECRET error.
Events and errors
Events and errors are essential to managing the behavior of user-driven encryption behavior. End-to-end encryption uses the shared secret model: everyone in the session is expected to use the same secret to encrypt their media and decrypt everyone else's.
The new error code is OTC_SESSION_INVALID_ENCRYPTION_SECRET and will be returned as the result code of the set_encryption_secret method, not in the on_error callback.
If a client tries to set an invalid encryption secret for a session, the otc_session_callbacks.on_error() returns an error code set to OTC_SESSION_INVALID_ENCRYPTION_SECRET. In the following example, a session is initialized with an empty (and thus invalid) encryption secret:
If a user tries to publish in an end-to-end encrypted session without having specified an encryption secret, calling the otc_session_publish() function results in the otc_publisher_callbacks.on_error() function being called with an error that has the code set to OTC_SESSION_ENCRYPTION_SECRET_MISSING. For the best user experience, the application should validate a user-supplied secret before calling the otc_session_publish() function:
If a subscriber is unable to decode a stream's media due to an incorrect encryption secret, the subscriber_callbacks.on_error() function is called with an error that has the code set to OTC_SUBSCRIBER_ENCRYPTION_SECRET_MISMATCH. It is important to communicate to the user that media is not being received due to an encryption mismatch and not due to a connection failure or audio/video issue:
If a subscriber encounters an internal error while decrypting a packet, the subscriber_callbacks.on_error() function is called with an error that has the code set to OTC_SUBSCRIBER_DECRYPTION_INTERNAL_ERROR.