Как сделать шифрование / дешифрование на основе открытого ключа 1-X или Y-X-X в NodeJs? - PullRequest
0 голосов
/ 13 ноября 2018

Я хотел бы иметь возможность шифровать данные с использованием открытых ключей и дешифровать зашифрованные данные с помощью закрытых ключей.

Шифрование, по существу, должно принимать входные данные:

  1. Очистить данные длябыть зашифрованным
  2. Список нескольких открытых ключей
  3. Минимальное количество закрытых ключей, соответствующих тем открытым ключам, которые необходимы для расшифровки зашифрованных

Как это можнобыть сделано в NodeJs?


Сценарии

В конкретных сценариях, где в системе 5 пользователей (A - E) с парами криптографических ключей.

Сценарий 1-из-X:

  • encrypted = crypto_encrypt(clearText, [A.publicKey, B.publicKey], 1) (1-из-2)
  • decrypted = crypto_decrypt(encrypted, [A.privateKey])
    • успех : decrypted === clearText
    • , поскольку A.publicKey использовалось в шифровании
  • decrypted = crypto_decrypt(encrypted, [C.privateKey])
    • ошибка : невозможно расшифровать
    • , поскольку C.publicKey не использовалось в шифровании

Сценарий Y-of-X:

  • encrypted = crypto_encrypt(clearText, [A.publicKey, B.publicKey, C.publicKey], 2)(2-из-3)
  • decrypted = crypto_decrypt(encrypted, [A.privateKey, C.privateKey])
    • успех : decrypted === clearText
    • , поскольку в шифровании использовались A.publicKey и C.publicKey
  • decrypted = crypto_decrypt(encrypted, [C.privateKey, E.privateKey])
    • ошибка : не удалось расшифровать
    • , поскольку при шифровании C.publicKey E.publicKey не было

В идеале ...

  • Как минимум мне нужно иметь возможность поддерживать сценарий 1-из-X, но если Y-of-X также возможен, это будетлучше
  • Фактические пары ключей здесь не так важны, это может быть RSA, может быть любая из эллиптических кривых.Если метод поддерживает несколько разных и позволяет выбирать, лучше бы
  • Предпочтительно не привязывать к использованию какого-либо конкретного набора инструментов или фреймворка

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Как отметил Люк Джошуа Парк в комментариях, это звучит как сценарий использования учебника для секретной схемы обмена . В частности, я бы порекомендовал вам:

  1. Генерация случайного ключа AES (или другого симметричного шифра). Обязательно используйте для этого криптографически безопасный ГСЧ (например, Crypto.randomBytes () ), поскольку злоумышленник, который может угадать этот ключ, может также взломать всю схему!
  2. Зашифруйте данные с помощью этого ключа, используя аутентифицированный режим шифрования, такой как AES-SIV (как предусмотрено, например, miscreant ).
  3. Разделите ключ AES на несколько долей, используя Схема совместного доступа Шамира с желаемым порогом восстановления. (Некоторые реализации JS, которые я обнаружил при быстром поиске в Google, включают secrets.js , jsss и ThresholdJS .)
  4. Зашифруйте каждую папку с помощью открытого ключа другого пользователя.
  5. Отправьте каждому пользователю его зашифрованный общий ресурс и копию зашифрованных данных AES.

Отказ от ответственности: Я не проверял безопасность или правильность любого из API или библиотек, указанных выше. Криптографические методы, которые, по их утверждению, используются, кажутся разумными и подходящими для этой задачи, но я не могу гарантировать, что они были реализованы безопасно и правильно. Предостережение emptor.

Чтобы расшифровать данные, каждый пользователь может сначала расшифровать свою долю ключа AES, используя свой закрытый ключ, а затем можно объединить достаточное количество расшифрованных общих ресурсов (используя ту же реализацию секретного обмена Shamir, которая использовалась для их создания). ) восстановить исходный ключ AES, который затем можно использовать для расшифровки (и проверки целостности) данных.

Обратите внимание, что секретный обмен Шамиром подразумевает, что пользователи, которые объединяют свои акции, чтобы восстановить секрет, будут доверять друг другу, а не лгать о своих акциях или иным образом плохо себя вести. Если это не обязательно так, злоумышленник может обмануть других, используя различные способы & mdash; возможно, наиболее просто: подождать, пока все остальные покажут им свою долю, а затем отказаться от раскрытия своей доли другим. В общем, предотвращение таких атак практически невозможно без помощи какой-либо взаимно доверяющей стороны.

Однако, по крайней мере, использование режима шифрования, такого как AES-SIV со встроенной аутентификацией , должно гарантировать, что пользователи обнаружат, является ли восстановленный ключ AES неправильным, поскольку дешифрование затем завершится неудачно. Если вы хотите быть в этом более уверенным, вы можете захотите также отправить каждому из пользователей защищенный криптографический хеш (например, SHA-512 ) ключа AES, чтобы они можно проверить его правильность перед попыткой расшифровки.

0 голосов
/ 14 ноября 2018

PGP может сделать это.

Специально для узла, openpgpjs имеет раздел в README - https://github.com/openpgpjs/openpgpjs#encrypt-and-decrypt-string-data-with-pgp-keys - который может быть сжат в:

    const encryptedText = await openpgp.encrypt({ message: clearText, publicKeys });
    const decryptedText = await openpgp.decrypt({ message: encryptedText, privateKeys });

Тем не менее:

  • для количества ключей, необходимых для дешифрования, он поддерживает только сценарий 1 из многих, а не более общий сценарий для некоторых из многих, который в идеале вы хотели бы
  • поддерживает как ключи RSA, так и многие ключи на основе эллиптической кривой, но формат ключа предназначен для использования PGP, как следует из названия библиотеки (поэтому он специфичен для цепочки инструментов PGP)
...