Use sensitive ops and mem limits to derive key

This commit is contained in:
Vishnu Mohandas 2021-03-18 15:26:40 +05:30
parent c3ada5c6f7
commit dcbe7d4c4e
5 changed files with 47 additions and 18 deletions

View file

@ -55,10 +55,12 @@ export default function Credentials() {
const { passphrase } = values;
const kek: string = await cryptoWorker.deriveKey(
passphrase,
keyAttributes.kekSalt
keyAttributes.kekSalt,
keyAttributes.opsLimit,
keyAttributes.memLimit,
);
if (await cryptoWorker.verifyHash(keyAttributes.kekHash, kek)) {
try {
const key: string = await cryptoWorker.decryptB64(
keyAttributes.encryptedKey,
keyAttributes.keyDecryptionNonce,
@ -73,7 +75,8 @@ export default function Credentials() {
setKey(SESSION_KEYS.ENCRYPTION_KEY, { encryptionKey });
setData(LS_KEYS.SESSION, { sessionKey, sessionNonce });
router.push('/gallery');
} else {
} catch (e) {
console.error(e);
setFieldError('passphrase', constants.INCORRECT_PASSPHRASE);
}
} catch (e) {

View file

@ -25,6 +25,12 @@ interface formValues {
confirm: string;
}
interface KEK {
key: string;
opsLimit: number;
memLimit: number;
}
export default function Generate() {
const [loading, setLoading] = useState(false);
const [token, setToken] = useState<string>();
@ -54,14 +60,13 @@ export default function Generate() {
const cryptoWorker = await new CryptoWorker();
const key: string = await cryptoWorker.generateMasterKey();
const kekSalt: string = await cryptoWorker.generateSaltToDeriveKey();
const kek: string = await cryptoWorker.deriveKey(
const kek: KEK = await cryptoWorker.deriveSensitiveKey(
passphrase,
kekSalt
);
const kekHash: string = await cryptoWorker.hash(kek);
const encryptedKeyAttributes: B64EncryptionResult = await cryptoWorker.encryptToB64(
key,
kek
kek.key
);
const keyPair = await cryptoWorker.generateKeyPair();
const encryptedKeyPairAttributes: B64EncryptionResult = await cryptoWorker.encryptToB64(
@ -71,13 +76,14 @@ export default function Generate() {
const keyAttributes = {
kekSalt,
kekHash: kekHash,
encryptedKey: encryptedKeyAttributes.encryptedData,
keyDecryptionNonce: encryptedKeyAttributes.nonce,
publicKey: keyPair.publicKey,
encryptedSecretKey:
encryptedKeyPairAttributes.encryptedData,
secretKeyDecryptionNonce: encryptedKeyPairAttributes.nonce,
opsLimit: kek.opsLimit,
memLimit: kek.memLimit,
};
await putAttributes(
token,

View file

@ -1,6 +1,7 @@
export interface keyAttributes {
kekSalt: string;
kekHash: string;
encryptedKey: string;
keyDecryptionNonce: string;
opsLimit: number;
memLimit: number;
}

View file

@ -255,20 +255,39 @@ export async function hash(input: string) {
);
}
export async function deriveKey(passphrase: string, salt: string) {
export async function deriveKey(passphrase: string, salt: string, opsLimit: number, memLimit: number) {
await sodium.ready;
return await toB64(
sodium.crypto_pwhash(
sodium.crypto_secretbox_KEYBYTES,
await fromString(passphrase),
await fromB64(salt),
sodium.crypto_pwhash_OPSLIMIT_INTERACTIVE,
sodium.crypto_pwhash_MEMLIMIT_INTERACTIVE,
opsLimit,
memLimit,
sodium.crypto_pwhash_ALG_DEFAULT
)
);
}
export async function deriveSensitiveKey(passphrase: string, salt: string) {
await sodium.ready;
const key = await toB64(
sodium.crypto_pwhash(
sodium.crypto_secretbox_KEYBYTES,
await fromString(passphrase),
await fromB64(salt),
sodium.crypto_pwhash_OPSLIMIT_SENSITIVE,
sodium.crypto_pwhash_MEMLIMIT_SENSITIVE,
sodium.crypto_pwhash_ALG_DEFAULT
)
);
return {
'key': key,
'opsLimit': sodium.crypto_pwhash_OPSLIMIT_SENSITIVE,
'memLimit': sodium.crypto_pwhash_MEMLIMIT_SENSITIVE,
}
}
export async function generateMasterKey() {
await sodium.ready;
return await toB64(sodium.crypto_kdf_keygen());

View file

@ -76,8 +76,12 @@ export class Crypto {
return libsodium.verifyHash(hash, input);
}
async deriveKey(passphrase, salt) {
return libsodium.deriveKey(passphrase, salt);
async deriveKey(passphrase, salt, opsLimit, memLimit) {
return libsodium.deriveKey(passphrase, salt, opsLimit, memLimit);
}
async deriveSensitiveKey(passphrase, salt) {
return libsodium.deriveSensitiveKey(passphrase, salt);
}
async decryptB64(data, nonce, key) {
@ -104,10 +108,6 @@ export class Crypto {
return libsodium.generateSaltToDeriveKey();
}
async deriveKey(passphrase, salt) {
return libsodium.deriveKey(passphrase, salt);
}
async generateKeyPair() {
return libsodium.generateKeyPair();
}