Недавно пришло время заняться функцией в моем проекте бессерверной бухгалтерской книги, которую я хотел в течение некоторого времени, но откладывал… шифрование.



Concords Ledger не имеет централизованной базы данных, каждый документ хранится только в браузере в виде криптографически подписанной записи транзакций. Реестр доступен для загрузки, а также имеет интеграцию с Solid для удаленного хранения.

Чтобы защитить эти необработанные данные от посторонних глаз за пределами приложения, мне нужно рассмотреть решение для шифрования, и я хочу, чтобы оно было встроено в продукт.

Шифрование паролей

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

Признание: я мало что узнал об этом. Я последовал отличному примеру и объяснению создания шифрования паролей с помощью WebCryptoAPI и использовал его.



OpenPGP

Затем мне нужен был способ шифрования личности. Идентификация является основной частью приложения Ledger. Все транзакции в реестре подписываются с помощью ключа подписи ECDSA и могут быть проверены через его открытый аналог. Поэтому я стремился найти способ прямого шифрования личности из приложения.

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



Используя библиотеку OpenPGP Javascript, я заменил идентификатор ECDSA в решении на подписи OpenPGP и добавил шифрование на основе ключа.

Я нашел OpenPGP довольно сложным, чтобы получить достойную реализацию, которая была бы гибкой. Поскольку теперь я пытался повторно использовать удостоверения PGP, управление ключами стало требованием к моему решению. Теперь мне нужно было загрузить существующие ключи OpenPGP и сохранить сеанс пользователя. Что быть бессерверным было далеко не идеальным.

Поэтому я копнул немного глубже, чтобы понять, почему я должен использовать OpenPGP, и обнаружил много негатива, связанного с PGP, например: https://moxie.org/2015/02/24/gpg-and-me.html.

Поэтому я обратился к /crypto Reddit, чтобы спросить: Уместен ли OpenPGP при построении шифрования в программном обеспечении? Ответ привел меня к тому, что я обратился к Age за шифрованием.

Возраст



Age выглядит великолепно, это популярная библиотека, которая кажется простой в концепции для реализации интероперабельного шифрования с использованием четко определенного стандарта.

Однако здесь есть небольшая проблема: Age написана на Go, а мое приложение бессерверное, просто Javascript работает в браузере.

Но в репозитории Age GitHub есть ссылка на реализацию Rust, Rage. Это обнадеживает. У меня еще не было возможности использовать WebAssembly, но я знаю, что Rust поддерживается, что привело меня в ярость-васм.

Идеальный! Оболочка WASM реализации Rust стандарта шифрования Age (написана на Go). Что было на удивление легко интегрировать. У меня уже было приложение, предназначенное для поддержки как шифрования на основе ключа, так и шифрования с помощью пароля — это два варианта, экспортированные через библиотеку rage-wasm. Несколько изменений в моей функции компонуемое шифрование (мне нравится VueJS), а мое шифрование на основе пароля и ключа теперь использует Rage.

Поскольку я больше не использую OpenPGP для шифрования, я отменил изменения, внесенные для подписей транзакций, обратно на использование WebCryptoAPI со сгенерированными ключами ECDSA.

Заключение

Шифрование — это кроличья нора, а интероперабельность сложна. Я решил добавить безопасное шифрование в свое клиентское приложение и, думаю, достиг этой цели.

Я буду придерживаться Age как единственной первоклассной интеграции для шифрования в продукте. Если возраст не для вас, бухгалтерскую книгу всегда можно загрузить в виде необработанного JSON и зашифровать по своему усмотрению… Вам просто нужно расшифровать ее вручную, прежде чем открывать бухгалтерскую книгу в приложении.

Что дальше?

Я хотел бы расширить функцию шифрования, изучив шифрование на основе транзакций. Внедрение детальных разрешений для конфиденциальных данных при сохранении неизменной целостности леджера за счет использования открытых ключей Age.