This key is used to safeguard the user’s mnemonic and wallet keys from attackers. We recommend an encryption key that is generated with entropy or pbkdf2 hash from a strong user-provided password or PIN.
Keep the encryption key extremely safe, as it grants access to the user's wallets and mnemonics. On Mobile iOS, consider storing the Encryption Key in Secure Enclave.
Example: Create and store encryption key to local storage
import { getRandomBytes } from '@railgun-community/wallet';
import { hashPasswordString } from './hash-service';
export const setEncryptionKeyFromPassword = async (password: string): Promise<string> => {
// Desired `password` comes from user input
const salt = getRandomBytes(16); // Generate salt
const [encryptionKey, hashPasswordStored] = await Promise.all([
hashPasswordString(password, salt, 100000), // Generate hash from password and salt
hashPasswordString(password, salt, 1000000), // Generate hash for stored password. Use more iterations for the stored value.
]);
await Promise.all([
..., // Save `hashPasswordStored` to local storage
..., // Save `salt` to local storage
]);
return encryptionKey;
};
Example: Get encryption key from local storage
import { hashPasswordString } from './hash-service';
export const getEncryptionKeyFromPassword = async (password: string): Promise<string> => {
// `password` comes from user input
const [storedPasswordHash, storedSalt] = await Promise.all([
..., // Fetch the previously stored password hash from local storage
..., // Fetch the previously stored `salt` from local storage
]);
const [encryptionKey, hashPassword] = await Promise.all([
hashPasswordString(password, storedSalt, 100000), // Same iterations as when generated, i.e. 100000
hashPasswordString(password, storedSalt, 1000000), // Same iterations as when generated, i.e. 1000000
]);
if (hashPasswordStored !== hashPassword) {
throw new Error('Incorrect password.');
}
return encryptionKey;
}