Создать закрытый ключ EC из материала ввода ключа в NodeJS - PullRequest
1 голос
/ 19 сентября 2019

Я хотел бы получить закрытый ключ эллиптической кривой из материала ввода ключа (мастер-ключ).Возможно ли это?

Попытки

Функция шифрования узла, crypto.generateKeyPair не принимает материал ввода ввода, а crypto.createPrivateKey только преобразует.pem для нативного KeyObject узла.

Я также не могу найти способ сделать это в OpenSSL, используя ecparam.Флаг -rand выглядит многообещающе, но не широко доступен (он не на моей машине).

Почему / Подробности

Мне нужно создать несколько секретов, и я хочу иметь их всеполученный из одного главного ключа.Это аналог HKDF.

Я использую ключи для ECDSA с кривой P-384 (secp384r1).

1 Ответ

3 голосов
/ 20 сентября 2019

Я удивлен, что вы думаете ecparam -rand file -genkey ... редко;он есть в каждой вышестоящей версии обратно по крайней мере до 0.9.8 в 2005 году, и это не та вещь, которую можно опустить опцией сборки (настройки), поэтому у вашей машины должна быть одна странная версия.Но это не имеет значения, потому что -rand не делает то, что вы хотите;он добавляет данные файла в «пул» ГСЧ, но не заменяет его , поэтому он не дает вам детерминированного генерирования ключа.

Как прокомментировал Вудсток,для всех практических целей необработанный закрытый ключ P-384 находится всего в 384 битах от любого хорошего генератора случайных чисел или детерминистически от любой равномерной случайной функции.Технически вы должны исключить ноль и значения, большие или равные порядку (под) группы n, но эти исключения настолько малы относительно 2 ^ 384, что практически нет шансов, что хороший случайный выбор ударит их в течение жизни Землии, возможно, вселенной.Возможно, вы захотите посмотреть, как работает «иерархический детерминированный» биткойн-ключ, известный как BIP 32 , хотя, конечно, он делает 256-битные ключи для secp256k1.

Это оставляет вам проблему с преобразованием необработанного ключа в форму, используемую криптоузлом nodejs (которая является довольно тонкой оболочкой библиотеки openssl) и / или командной строкой openssl.Для этого следуйте принципам Как преобразовать ключ ECDSA в формат PEM , который, в свою очередь, основан на https://bitcoin.stackexchange.com/questions/66594/signing-transaction-with-ssl-private-key-to-pem, за исключением использования OID и размера (-ов) для P-384 вместо secp256k1,В частности, объедините

  • 7 байтов, представленных в шестнадцатеричном виде 303e0201010430
  • 48 байтов (384 бит) необработанного закрытого ключа
  • 9 байтов, представленных в шестнадцатеричном видепо a00706052b81040022 (для P-384 aka secp384r1)

В зависимости от вашего языка (-ов) или инструмента (-ов) вы можете обрабатывать эти значения напрямую или объединять шестнадцатеричные представления, а затем преобразовывать в двоичный файл.Результатом является 'DER' (двоичная) форма закрытого ключа специфичного для алгоритма (SEC1) (только), который может быть прочитан nodejs 11 или 12 crypto.createPrivateKey( {key:(data), format:'der', type:'sec1'} ), а также командной строкой openssl ec -inform der.

Если вы предпочитаете текстоподобные вещи (например, для вырезания и вставки), преобразуйте DER выше в base64, разбейте на строки из 64 символов (отличных от последнего) и добавьте строки -----BEGIN EC PRIVATE KEY----- до и -----END EC PRIVATE KEY------ после.Это формат PEM, и он может быть прочитан createPrivateKey без каких-либо других опций и openssl ec без каких-либо опций.

...