Безопасная отправка писем со статических сайтов с помощью стороннего API

Это те же самые шаги, которые я выполняю, чтобы эта форма работала. Если вы обнаружите какие-либо недостатки, я должен быть первым, кто узнает :)

Я искал способ отправлять электронные письма и / или другие данные со статического сайта с помощью стороннего почтового API. Есть несколько отличных сервисов для отправки писем, но ни один из них не является «безопасным». Под безопасностью я подразумеваю, что все, что человек отправляет мне через почтовый API, доставляется в виде обычного текста. Это означает, что любой, у кого есть доступ к серверу API, может видеть любую почту, отправленную мне через их API. И я тоже не хочу настраивать свой собственный сервер только для отправки электронных писем.

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

Объяснение

Хорошо. Тут у вас может возникнуть вопрос, а что, черт возьми, за ключ? Чтобы ответить на этот вопрос, ключ - это уникальный идентификатор, с помощью которого человек может зашифровать сообщение и впоследствии расшифровать его по запросу.

Итак, в чем выгода? Что ж, плюсов много! Во-первых, никто другой, кроме вас, никогда не смог бы в него заглянуть (если только вы не поделитесь своим секретным ключом). Он не позволит никому изменить сообщение, которое отправляется вам на полпути.

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

  • Закрытый ключ: это криптографический ключ, используемый для дешифрования. По своей природе это секретный ключ, и он должен быть только у вас. Как только вы подумаете, что потеряли ключ или его обманули, самое время получить новый. И аннулировать предыдущий открытый и закрытый ключ.
  • Открытый ключ: он поставляется вместе с вашим закрытым ключом в виде пары. Этот ключ используется для шифрования, чтобы можно было расшифровать закрытый ключ. Этим ключом можно свободно поделиться с кем угодно. Сообщение, зашифрованное с помощью открытого ключа, должно быть расшифровано с использованием закрытого ключа этой пары. У меня есть открытый ключ здесь. Отправить зашифрованное сообщение, ха-ха ..
  • Отпечаток пальца. Отпечаток пальца - это короткая версия (состоящая из байтов) более длинного открытого ключа. Он используется для упрощения управления ключами в некоторых приложениях. Он создается путем применения криптографической хеш-функции в открытом ключе.

Реализация

Шаги по реализации:

  1. Мы сгенерируем для нас пару ключей. Так что мы можем зашифровать / расшифровать сообщение.
  2. Зашифруйте сообщение, используя наш собственный открытый ключ.
  3. Отправляйте сообщения с нашего статического сайта с помощью API доставки почты.
  4. Как только API доставит нам сообщение, расшифруйте его с помощью закрытого ключа.
  5. Этого должно быть достаточно! Посмотрим, как пойдет.

Создать пару ключей

Для обработки шифрования мы будем использовать OpenPGP. OpenPGP - это стандарт шифрования, производный от PGP. GnuPG (gpg) - это программное обеспечение, реализующее OpenPGP. Обычно GnuPG предустановлен. Если он у вас не установлен, скачайте отсюда.

Pretty Good Privacy (PGP) - это программа шифрования, которая обеспечивает криптографическую конфиденциальность и аутентификацию для передачи данных. PGP используется для подписи, шифрования и дешифрования текстов, сообщений электронной почты, файлов, каталогов и целых разделов диска, а также для повышения безопасности сообщений электронной почты. Фил Циммерманн разработал PGP в 1991 году. - Википедия

  • Создайте новый ключ из командной строки: введите gpg --full-gen-key в терминале, нажмите Enter и следуйте инструкциям на экране.
  • Чтобы узнать отпечаток вашего ключа, запустите gpg --fingerprint.
  • Чтобы экспортировать открытый ключ (необходимо), запустите gpg --armor --export FINGERPRINT > public-key.txt. Это сгенерирует защищенный открытый ключ ASCII и сохранит его в public-key.txt.

Зашифровать данные

Теперь, когда у нас есть ключ, мы можем продолжить и сгенерировать зашифрованный текст, используя открытый ключ. Для шифрования / дешифрования мы будем использовать библиотеку под названием openPGP.js (разработанную Signal). Вы можете просто добавить эту библиотеку в проект с помощью CDN.

Начнем с написания кодов.

Создать форму в HTML

Скопируйте следующий HTML-код внутри index.html (создать файл в корне проекта)

<html>
  <body>
    <form action="">
      <input type="email" placeholder="[email protected]" /> <br />
      <input type="name" placeholder="Abdus" /> <br />
      <textarea
        name="message"
        cols="30"
        rows="10"
        placeholder="Your awesome message"
      ></textarea
      ><br />
      <input type="submit" value="Encrypt and Send" />
    </form>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/openpgp/4.6.2/openpgp.min.js"
      integrity="sha256-txcrHjb7Yt1zrebRnGkk5OwDkoBrvJTjvJx5b7qBtWc="
      crossorigin="anonymous"
    ></script>
    <script src="assets/js/main.js"></script>
  </body>
</html>

Также скопируйте следующий код JavaScript внутри assets/js/main.js (создать в корне проекта)

const PUBLIC_KEY = `PUT YOUR PUBLIC KEY HERE(copy it from public-key.txt we generated earlier)`;

async function encrypt(message) {
  const enc_message = await openpgp.encrypt({
    message: openpgp.message.fromText(message),
    armor: true, // export as ascii armored text
    publicKeys: (await openpgp.key.readArmored(PUBLIC_KEY)).keys,
  });

  sendMail(enc_message.data); // send the mail
}

document.querySelector('form').addEventListener('submit', e => {
  // dom manipulation
  const sender = {
    name: document.querySelector('#name').value,
    email: document.querySelector('#email').value,
    message: document.querySelector('#message').value,
  };

  // prevent page from reload on form submit
  e.preventDefault();

  // finally call our encrypt function
  encrypt(`${sender.name} <${sender.email}> \n\n\n ${sender.message}`);
});

function sendMail(encrypted_message) {
  // here, we will make a POST request to formspree
  // so that formspree could deliver our data
  fetch('https://formspree.io/YOUR_FORMSPREE_ID', {
    method: 'POST',
    mode: 'no-cors',
    body: JSON.stringify({
      message: encrypted_message,
    }),
  })
    .then(console.log)
    .catch(console.log);
}

Вышеупомянутый JavaScript в значительной степени не требует пояснений. У вас не должно возникнуть особых проблем. Если вы столкнетесь с какой-либо проблемой, дайте мне знать, используя эту форму.

Также нам понадобится аккаунт Formspree. Это API для доставки данных / электронной почты нашей формы. Создать учетную запись в Formspree очень просто. Вы можете сделать это.

Расшифровать сообщение

Как только вы получите сообщение через Formspree, самое время его расшифровать и посмотреть, что внутри него. Для этого мы будем использовать gpg-клиент командной строки. Перед расшифровкой сохраните зашифрованный текст в файл и назовите его something.pgp. Затем, наконец, запустите gpg --decrypt something.pgp (при условии, что something.pgp находится в текущем рабочем каталоге). Вывод должен быть направлен на стандартный вывод, то есть (в основном) в окно терминала / cmd. Чтобы сохранить его в файл, добавьте к команде этот флаг: --output something.txt.

Если вы предпочитаете приложение с графическим интерфейсом, вы найдете множество приложений с открытым исходным кодом бесплатно. Просто убедитесь, что он реализует стандарты OpenPGP.

Вот и все! К этому времени у вас должно быть зашифрованное электронное письмо, которое безопасно доставляется с помощью стороннего веб-сайта с вашего статического сайта.

  1. Этот процесс шифрования не подписывает документ.
  2. Всегда лучше использовать собственный сервер.
  3. Никогда не разглашайте свой закрытый ключ. Никогда.

Первоначально опубликовано на https://abdus.xyz.