Add encryption (#642)

* Add encryption

In order to avoid the server being able to read the content of the scene, this PR implements local encryption and decryption. This implements the algorithm described in #610.

Right now the server doesn't support uploading binary files. I mocked the server with comments. @lipis, could you add support on the server and update this PR? I added a bunch of TODO: that tell you where to comment/uncomment in order to get the server flow going.

To test locally right now:
- Import: Open http://localhost:3000/#json=1234,5oYVOnGpWYPPTz19-PMYYw and see a square
- Export: Click the export link and see the right url with the private key + the encrypted binary in the console

Fixes #610

* backend_v2

* v2
This commit is contained in:
Christopher Chedeau 2020-02-05 07:35:51 -08:00 committed by GitHub
parent c7d7d65e1b
commit 2dd1796351
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 137 additions and 49 deletions

View file

@ -302,12 +302,14 @@ export class App extends React.Component<any, AppState> {
return true;
}
private async loadScene(id: string | null) {
private async loadScene(id: string | null, k: string | undefined) {
let data;
let selectedId;
if (id != null) {
data = await importFromBackend(id);
addToLoadedScenes(id);
// k is the private key used to decrypt the content from the server, take
// extra care not to leak it
data = await importFromBackend(id, k);
addToLoadedScenes(id, k);
selectedId = id;
window.history.replaceState({}, "Excalidraw", window.location.origin);
} else {
@ -342,7 +344,17 @@ export class App extends React.Component<any, AppState> {
const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id");
this.loadScene(id);
if (id) {
// Backwards compatibility with legacy url format
this.loadScene(id, undefined);
} else {
const match = window.location.hash.match(
/^#json=([0-9]+),([a-zA-Z0-9_-]+)$/,
);
if (match) {
this.loadScene(match[1], match[2]);
}
}
}
public componentWillUnmount() {
@ -1854,7 +1866,7 @@ export class App extends React.Component<any, AppState> {
<StoredScenesList
scenes={scenes}
currentId={this.state.selectedId}
onChange={id => this.loadScene(id)}
onChange={(id, k) => this.loadScene(id, k)}
/>
);
}