add optional Argon2id password wrap for zk uploads.
Wrap the image DEK for password-protected batches, keep the URL fragment as a separate secret, and extend prepare/decrypt helpers with tests.
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { deriveZkWrapKeyBytes } from '@/utils/crypto/deriveZkWrapKeyBytes';
|
||||
import { generateDek } from '@/utils/crypto/generateDek';
|
||||
|
||||
describe('deriveZkWrapKeyBytes', () => {
|
||||
const salt = new Uint8Array([8, 7, 6, 5, 4, 3, 2, 1, 0, 9, 8, 7, 6, 5, 4, 3]);
|
||||
const fragmentSecret = generateDek();
|
||||
const password = 'wrap-password';
|
||||
|
||||
it('returns a 32-byte wrap key', async () => {
|
||||
const wrapKey = await deriveZkWrapKeyBytes(password, salt, fragmentSecret);
|
||||
|
||||
expect(wrapKey.byteLength).toBe(32);
|
||||
});
|
||||
|
||||
it('is deterministic for the same inputs', async () => {
|
||||
const first = await deriveZkWrapKeyBytes(password, salt, fragmentSecret);
|
||||
const second = await deriveZkWrapKeyBytes(password, salt, fragmentSecret);
|
||||
|
||||
expect(first).toEqual(second);
|
||||
});
|
||||
|
||||
it('binds the URL fragment secret into the wrap key', async () => {
|
||||
const otherFragment = generateDek();
|
||||
|
||||
const wrapKeyA = await deriveZkWrapKeyBytes(password, salt, fragmentSecret);
|
||||
const wrapKeyB = await deriveZkWrapKeyBytes(password, salt, otherFragment);
|
||||
|
||||
expect(wrapKeyA).not.toEqual(wrapKeyB);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user