This tutorial covers getting up and running with Tanker Core. You are going to implement a simple web application containing a text area. The contents of the text area will be encrypted and decrypted using Tanker Core.

This tutorial is designed for developers who want to get started with Tanker's end-to-end encryption SDKs from scratch. It assumes that you have no prior experience with Tanker.

After having completed this tutorial, you will know:

  • How to install the Core SDK inside a JS application
  • How to initialize the Core SDK
  • How to encrypt and decrypt data using Tanker

1. The goal

Diff notations are used to highlight the code changes that need to be made in each step, e.g.

File: src/File.js
const previousCode = 'my code; // Code to remove const newCode = 'my new code'; // Code to add const unchangedCode = 'unchanged';

Let's start!

2. Create a React application

Note

You're about to create a boilerplate React application. However, Tanker is not tied to React and can be used in any kind of JavaScript project.

To be able to use the create-react-app command-line tool below, please verify that you have both Node.js 8.16.0, 10.16.0 or later version, and yarn on your development machine.

When ready, create a React application named encryption-in-browser:

yarn global add create-react-app
create-react-app encryption-in-browser

This will configure a default React application. To start the app, simply type:

cd encryption-in-browser
yarn start

3. Prepare the App Component

Replace the default content of src/App.js by this brand new React Component:

File: src/App.js
import React from 'react'; class App extends React.Component { constructor(props){ super(props); this.state = { ready: false }; } async componentDidMount() { this.setState({ ready: true }); } render() { const { ready } = this.state; if (!ready) return <section><p>Loading...</p></section>; return <section><p>Ready!</p></section>; } } export default App;

The App state only contains a ready boolean for now, but this component will soon prove useful in handling the state and the asynchronous initialization of Tanker.

4. Set up

Add the dependencies

Add the @tanker/client-browser package to your application dependencies:

yarn add @tanker/client-browser

Add the @tanker/fake-authentication package too:

yarn add @tanker/fake-authentication

Tanker identifies users before allowing them to perform cryptographic operations. To this end, we will need to provide Tanker identities.

The purpose of the @tanker/fake-authentication package is to simulate the presence of a backend service that can distribute these identities to the users of your tutorial application.

Note

Tanker identities contain information allowing users to access their encrypted data. While they do not grant access to any data by themselves, they should be managed securely on your server in a real application.

Do not use the @tanker/fake-authentication package in production. Instead, please consult the guide on user management.

Get an appId

Warning

You will need a Tanker account to follow the rest of the tutorial. If you don't have one, please sign up on dashboard.tanker.io

To initialize both Tanker Core and FakeAuthentication, you will need an appId. To get one, create a new application named EncryptionInBrowser in the Tanker dashboard and copy the generated appId.

Initialize Tanker Core and FakeAuthentication

Add the following lines to src/App.js:

File: src/App.js
import FakeAuthentication from '@tanker/fake-authentication'; import Tanker from '@tanker/client-browser'; const appId = 'YOUR_APP_ID'; class App extends React.Component { constructor(props){ super(props); this.tanker = new Tanker({ appId }); this.fakeAuth = new FakeAuthentication({ appId }); this.state = { ready: false }; } // ... }

5. Start a session

Encrypting data requires having a started session.

We will generate a Tanker identity using the FakeAuthentication instance and use this identity to call tanker.start() when the component mounts.

File: src/App.js
import FakeAuthentication from '@tanker/fake-authentication'; import Tanker from '@tanker/client-browser'; const appId = 'YOUR_APP_ID'; const alice = { email: 'alice@tanker-tuto.io', passphrase: 'this is a secure passphrase', }; class App extends React.Component { // ... async componentDidMount() { const { email, passphrase } = alice; const { identity } = await this.fakeAuth.getIdentity(email); const status = await this.tanker.start(identity); switch (status) { // 1. The identity is not yet known to Tanker, it must be registered. case Tanker.statuses.IDENTITY_REGISTRATION_NEEDED: await this.tanker.registerIdentity({ passphrase }); // The session is started break; // 2. The identity is known to Tanker, but the user is using a new device. case Tanker.statuses.IDENTITY_VERIFICATION_NEEDED: await this.tanker.verifyIdentity({ passphrase }); // The session is started break; // 3. Nothing to be done, the session is started. case Tanker.statuses.READY: break; default: throw new Error(`Unhandled status: ${status}`); } this.setState({ ready: true }); } render() { // ... } }

Note that we hard-code the user email and the passphrase for simplicity.

You can find more information in the guide about starting a session.

6. Create a TextArea component

To input some text, we will create a new component named TextArea.

First, create a new file named TextArea.js in the src folder.

This component will display the following elements:

  • a text area to input text
  • a toggle button

When clicking on the button, the text will either be encrypted or decrypted. We'll use base64 to display the encrypted text.

Add the following code to src/TextArea.js:

File: src/TextArea.js
import React from 'react'; class TextArea extends React.Component { constructor(props) { super(props); this.state = { text: "", encrypted: false }; } onToggle = async () => { } onChange = (event) => { this.setState({ text: event.target.value }); } render() { const { text, encrypted } = this.state; return ( <div> <label htmlFor="text-input">Enter your message here</label> <br /> <textarea value={text} onChange={this.onChange} readOnly={encrypted} /> <br /> <input type="submit" onClick={this.onToggle} value={ encrypted ? 'Decrypt' : 'Encrypt' } /> </div> ); } } export default TextArea;

To render the component, add the following lines in src/App.js:

File: src/App.js
import FakeAuthentication from '@tanker/fake-authentication'; import Tanker from '@tanker/client-browser'; import TextArea from './TextArea'; const appId = 'YOUR_APP_ID'; const alice = { email: 'alice@tanker-tuto.io', passphrase: 'this is a secure passphrase', } class App extends React.Component { // ... render() { const { ready } = this.state; if (!ready) return <section><p>Loading...</p></section>; return <section><p>Ready!</p></section>; return <section><TextArea tanker={this.tanker} /></section>; }

7. Encrypt and decrypt

We passed the Tanker session to TextArea to implement the Encrypt/Decrypt button logic.

This is done by calling tanker.encrypt() and tanker.decrypt():

File: src/TextArea.js
import React from 'react'; import { toBase64, fromBase64 } from '@tanker/client-browser'; class TextArea extends React.Component { constructor(props) { super(props); this.state = { text: "", encrypted: false }; } onToggle = async () => { const { tanker } = this.props; const { encrypted, text } = this.state; if (encrypted) { const encryptedData = fromBase64(text); const clearText = await tanker.decrypt(encryptedData); this.setState({ text: clearText, encrypted: false }); } else { const encryptedData = await tanker.encrypt(text); const encryptedText = toBase64(encryptedData); this.setState({ text: encryptedText , encrypted: true }); } } onChange = (event) => { this.setState({ text: event.target.value }); } render() { const { text, encrypted } = this.state; return ( <div> <label htmlFor="text-input">Enter your message here</label> <br /> <textarea value={text} onChange={this.onChange} readOnly={encrypted} /> <br /> <input type="submit" onClick={this.onToggle} value={ encrypted ? 'Decrypt' : 'Encrypt' } /> </div> ); } } export default TextArea;

tanker.encrypt() returns a Uint8Array containing the encrypted data. To be able to show it in the text area, we use the base64 helpers provided by Tanker.

Congratulations!

We are done! You can run yarn start and try it out!

You now have a React application you can use to encrypt and decrypt user messages.

In a real application, you would of course have to replace @tanker/fake-authentication with your own user management backend, and integrate the Tanker identities in it. It goes beyond the scope of this tutorial, but you can read the guide about user's identity management for more information.

8. What's next?

Now that you've built your first application using Tanker, feel free to update it and experiment on your own.

For more details and to go beyond this example application, please refer to the Guides and API reference.