Skip to content
This repository has been archived by the owner on Nov 24, 2022. It is now read-only.

Commit

Permalink
feat: encryption and decryption (#313)
Browse files Browse the repository at this point in the history
* feat: adding encrypt and decrypt with function

* feat: local storage encrypt and redux decrypt

* feat: removed the encryption modal unneeded

* feat: added the salt to the password

* feat: removing scrypt async for diff package adding salt to localstorage
  • Loading branch information
Dudleyneedham authored Jan 14, 2021
1 parent bf0dfbf commit 33de94d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 7 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
"reselect": "^4.0.0",
"resolve": "1.6.0",
"sass-resources-loader": "^2.0.0",
"scrypt-js": "^3.0.1",
"source-map-loader": "^0.2.1",
"styled-components": "^4.1.3",
"ts-jest": "22.0.1",
Expand Down
33 changes: 26 additions & 7 deletions src/state/PersistentStore.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import { combineReducers, createStore, Store } from 'redux'
import nacl from 'tweetnacl'
import { u8aToHex } from '@kiltprotocol/sdk-js/build/crypto'
import {
encryption,
decryption,
passwordHashing,
} from '../utils/Encryption/Encryption'

import * as Attestations from './ducks/Attestations'
import * as Balances from './ducks/Balances'
Expand Down Expand Up @@ -50,10 +57,12 @@ class PersistentStore {
}

private static NAME = 'reduxState'
private static SALT = 'salt'

private static async deserialize(
obj: SerializedState
encryptedState: string
): Promise<Partial<State>> {
const obj = JSON.parse(encryptedState)
return {
attestations: Attestations.Store.deserialize(obj.attestations),
claims: Claims.Store.deserialize(obj.claims),
Expand Down Expand Up @@ -85,12 +94,21 @@ class PersistentStore {

public async init(): Promise<Store> {
const localState = localStorage.getItem(PersistentStore.NAME)
let salt = localStorage.getItem(PersistentStore.SALT)

if (!salt) {
salt = u8aToHex(nacl.randomBytes(24))
localStorage.setItem(PersistentStore.SALT, salt)
}

const password = await passwordHashing('password', salt)
let persistedState: Partial<State> = {}
if (localState) {
try {
persistedState = await PersistentStore.deserialize(
JSON.parse(localState)
)
const decryptedState = decryption(localState, password)
if (decryptedState) {
persistedState = await PersistentStore.deserialize(decryptedState)
}
} catch (error) {
console.error('Could not construct persistentStore', error)
}
Expand All @@ -117,10 +135,11 @@ class PersistentStore {
)

this.storeInternal.subscribe(() => {
localStorage.setItem(
PersistentStore.NAME,
PersistentStore.serialize(this.storeInternal.getState())
const serializedState = PersistentStore.serialize(
this.storeInternal.getState()
)
const encryptedState = encryption(serializedState, password)
localStorage.setItem(PersistentStore.NAME, JSON.stringify(encryptedState))
})

return this.storeInternal
Expand Down
30 changes: 30 additions & 0 deletions src/utils/Encryption/Encryption.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
encryptSymmetricAsStr,
decryptSymmetricStr,
CryptoInput,
EncryptedSymmetricString,
coToUInt8,
} from '@kiltprotocol/sdk-js/build/crypto'
import { scrypt } from 'scrypt-js'

export function encryption(
message: string,
secret: CryptoInput
): EncryptedSymmetricString {
return encryptSymmetricAsStr(message, secret)
}

export function decryption(data: string, secret: CryptoInput): string | null {
return decryptSymmetricStr(JSON.parse(data), secret)
}

export function passwordHashing(
password: string,
salt: string
): Promise<Uint8Array> {
const N = 1024
const r = 8
const p = 1
const dkLen = 32
return scrypt(coToUInt8(password), coToUInt8(salt), N, r, p, dkLen)
}

0 comments on commit 33de94d

Please sign in to comment.