ПРЕДУПРЕЖДЕНИЕ Следующее не предназначено для подтверждения преобразования паролей в ключи ECDH.Создание ключей ECDH из высокоэнтропийных, крипто-безопасных PRNG.
Я хочу взять секрет и сгенерировать из него открытый / закрытый ключ ECDH.
В браузереобычным способом было бы использовать PBKDF2 (или другие детерминированные байты) для генерации пары открытого / закрытого ключа ECDH в WebCrypto.
Следующий пример кода должен сделать это, но он генерирует исключение DOM в Chrome:
// Generate a random KDF key.
const priv = new Uint8Array(24)
crypto.getRandomValues(priv)
const kdfKey = await crypto.subtle.importKey(
'raw', priv, { name: 'PBKDF2' }, false, ['deriveKey'])
// Derive the ECDH key.
const salt = new Uint8Array(16)
const iterations = 2000
const hash = { name: 'SHA-512' }
const curve = { name: 'ECDH', namedCurve: 'P-384' }
const usages = ['deriveKey']
crypto.getRandomValues(salt)
const ecdhKey = await crypto.subtle.deriveKey({
name: 'PBKDF2', salt, iterations, hash
}, kdfKey, curve, true, usages) // throws.
Выше работает, когда алгоритм AES-GCM
(то есть, когда кривая заменяется, например, { name: 'AES-GCM', length: 256 }
), но другие алгоритмы также выдают исключения, поэтому я подозреваю, что я что-то упустил ... тонкий.
Я надеялся, что WebCrypto будет подходить для приема случайных битов и генерации пары открытого / секретного ключей ECDH.Похоже, что это может быть не так.
Альтернативой может быть использование PBKDF2
- deriveBits
, которое можно использовать для создания пары ключей ECDH вручную.Если это действительно единственный вариант, каков обычный алгоритм для преобразования случайных битов в открытый / закрытый ключ (т. Е. Ссылки и открытые реализации)?Если мне нужно что-то разработать, я, скорее всего, опубликую это здесь: интерес и обзор.
РЕДАКТИРОВАТЬ: Дополнительные подробности сценария использования
Использование PBKDF является попыткой избежать необходимостигенерировать открытый ключ (x
и y
) пары ключей ECDH, если задан (приватный) параметр d
.x
и y
являются производными и поэтому не требуют хранения, и у нас очень ограниченное хранилище данных - подходит только для закрытого ключа, например, 192 бита, более или менее (PBKDF может сгладить размер битатоже, но это в стороне).
Если WebCrypto вычислил x
и y
при заданном (псевдо) случайном d
параметре, желаемый результат может быть достигнут /проиллюстрировано следующим образом:
>>> curve = { name: 'ECDH', namedCurve: 'P-256' }
>>> k = await crypto.subtle.generateKey(curve, true, ['deriveKey'])
>>> pri = await crypto.subtle.exportKey('jwk', k.privateKey)
>>> delete pri.x
>>> delete pri.y
>>> k2 = await crypto.subtle.importKey('jwk', pri)
^^ errors
PBKDF используется для генерации (AES) ключей в многочисленных примерах.Я надеялся, что функциональность для вычисления x
и y
для эллиптических кривых, уже существующая в WebCrypto, будет доступна через PBKDF2 deriveKey
.
Альтернатива "сделай сам" в Javascript - эторазберите JWK / Base64 (вариант URL), затем используйте функцию большого целого с арифметикой по модулю (например, Маленькая теорема Ферма) и, наконец, напишите функции для сложения точек эллиптической кривой, удвоения и умножения.Что я и сделал ( ECC математика здесь ).Но я надеялся, что все это будет излишним, поскольку в WebCrypto существует код для выполнения именно этого, и я просто надеялся использовать либо importKey
, либо deriveKey
, чтобы использовать его.
Просто дляповторить: нет пользовательских паролей;использование такого ключа для генерации ключа ECDH считается неразумным.