Я хотел бы зашифровать данные, которые перемещаются между сервером и клиентом в моем веб-приложении. Я бы использовал SSL, но для этого требуется сертификат вместе с выделенным IP-адресом. У меня нет проблем с получением сертификата, но для выделенного IP-сервера мне требуется перейти на план бизнес-хостинга, который составляет 20 долларов США в месяц на моем веб-хосте. У меня нет никаких планов по этому поводу, поскольку я придерживаюсь своего платного хостинга в размере 20 долларов США в год.
Поэтому я хотел бы реализовать альтернативу SSL. Однако он делает больше, чем SSL. Помимо шифрования данных, отправленных туда и обратно, он также шифрует строки в базе данных. Я думал сделать что-то вроде этого:
Код JavaScript:
var transfer_key = 'whatever'; function encrypt(data, key) {...} function decrypt(data, key) {...} function send_data_to_server(url, data) { $.post(url, {'data' : encrypt(data, transfer_key) }, function(response) { var decrypted_response = JSON.parse(decrypt(response)); }); }
Код PHP:
$data = $_POST['data']; $transfer_key = 'whatever'; $storage_key = 'whatever2'; function encrypt($data, $key) {...} function decrypt($data, $key) {...} databaseQuery('INSERT INTO table VALUES (?)', encrypt($data, $storage_key)); $decrypted_data = decrypt($data, $transfer_key); $response = processData($decrypted_data); echo encrypt($transfer_key, $response);
Как вы можете видеть, данные, которые клиент отправляет на сервер, зашифрованы и наоборот. И данные в базе данных также зашифрованы. Теперь, конечно, я бы никогда не реализовал такие ключи. У меня, вероятно, был бы второй или третий ключ, который случайным образом генерируется для каждого пользователя. Таким образом, transfer_key может быть равно константе_ключи, объединенной со случайным ключом, а также для storage_key.
Будет ли это хорошей альтернативой SSL? Как я могу реализовать этот тип шифрования таким образом, что его сложно победить? Есть ли какие-то особые недостатки в этом подходе?
Вероятно, я собираюсь найти библиотеку JS, которая занимается шифрованием и использует расширение mcrypt PHP для серверной части. Я думал о Blowfish, может быть, AES256, но я не уверен, какой из них дает мне наилучшее соотношение силы шифрования в потреблении памяти.
Совет?
О, о. Удачи с этим. Вы посмотрели спецификацию TLS ? Как вы думаете, вы можете придумать что-то адекватное, которое будет проверено миллионами людей?
Нет, действительно, TLS уже много лет тестировалось и улучшалось настолько многими людьми, криптографами, которые ничего не делают, кроме как разрывать такие протоколы, было бы трудной задачей придумать что-то адекватное.
SSL был разработан экспертами в этой области, и они, конечно же, сначала подумали, что их протокол был абсолютно нерушимым. Но тогда была версия 2, затем 3, затем TLS v.1, v1.1 и теперь 1.2.
Если у вас нет опыта в разработке защищенных протоколов, вы должны придерживаться основного направления и использовать TLS / SSL.
Безопасность – одно из редких полей, где это имеет смысл, и на самом деле здорово идти с мейнстримом, поэтому я бы сказал, что добавленные деньги будут потрачены хорошо.
Редактировать:
Возможно, я был немного суров, и мне не было объяснений, почему ваш подход не может конкурировать с несколько сложным протоколом, таким как TLS, поэтому давайте проанализируем его:
1) Как бы вы сделали обмен ключами? Чтобы AES работал на обоих концах, вам нужно сделать обмен ключами , для симметричного шифрования обеим сторонам необходимо обладать одним и тем же ключом. Как вы сказали, вы хотели бы генерировать его случайно на клиенте – пока все хорошо. Первая проблема – вам нужно создать безопасное случайное число – иначе, например, используя встроенный генератор случайных чисел Javascript – злоумышленники смогут предсказать ваши случайные числа через некоторое время.
2) Допустим, вы овладели этим. Затем возникает следующая проблема: как вы можете отправить этот ключ на сервер безопасным образом, т. Е. Выполнить обмен ключами? Там вам потребуется какая-то форма проверки подлинности на стороне сервера, иначе кто-то может наложить как ваш сервер и сделать это:
3) Таким образом, вам нужна аутентификация сервера, по крайней мере, если не проверка подлинности клиента. Это будет означать, что вам нужна кривая для асимметричной криптографии с открытым ключом для шифрования / обертывания ключа с помощью открытого ключа сервера, чтобы только сервер мог его расшифровать.
4) После того, как вы освоили это, вы по-прежнему подвержены более вовлеченным формам атак, таких как атаки повтора, атаки « человек-в-середине-атаки» , отражения , …
5) Возможно, вам также нужна Perfect Forward Secrecy, чтобы после того, как ключ скомпрометирован, злоумышленник не сможет дешифровать прошлые данные. Для этого вам понадобится Диффи-Хеллман (предпочтительно в форме криптографии с эллиптической кривой ).
6) И последнее, но не менее важное: механизм сеанса, вероятно, также будет приятным, так что вы можете забрать предыдущие сеансы с уже установленными симметричными ключами, чтобы вы могли уменьшить нагрузку на сервер, не переустанавливая его снова, используя несколько ресурсоемких алгоритмов открытого ключа.
-> Добавьте еще несколько функций, например, безопасное согласование набора алгоритмов, которое подтверждают как клиент, так и сервер, и вы повторно выполнили протокол TLS.
Извините, если это звучит немного саркастично, но я знаю, что кажется соблазнительным бросить свои собственные криптограммы (это тоже забавно), но в конце вы должны придерживаться TLS: он (относительно) прост в использовании, он работает на транспорте (так что вы можете кодировать свои приложения так, как если бы не было никакого шифрования), и лучше всего, это безопасно.
EDIT: Ну, недавно были некоторые атаки, но почти все атаки использовали «человеческий фактор» в этих протоколах, атакуя сертификаты открытого ключа, которые поддерживают протокол (Comodo, DigiNotar и т. Д. – яркие примеры) или более загадочные особенности протокол, такой как согласование алгоритмов и т. д., но BEAST был впервые, когда TLS успешно атаковали на уровне криптографии, что интересно и страшно в то же время, потому что основы этой атаки известны уже несколько лет .
Тем не менее, с недавними исправлениями для BEAST на данный момент, я бы поспорил, что TLS по-прежнему является наилучшим вариантом для безопасной связи в Интернете, особенно по сравнению с решениями ручной работы.
Райан: Я говорю это в том, что я надеюсь, это лучший возможный способ: потребление памяти является абсолютным минимумом ваших проблем.
В этом нет ничего безопасного. Ничего. Ничего .
Он мертв от самой первой отправки этого javascript … Мне все равно, как долго ваши ключи или насколько случайны соль.
То, что у вас есть, не остановит кого-то, кто сидит в кафе, когда их ноутбук открывает захватывающие пакеты от перехвата ключей и может легко расшифровать все остальное, что вы проходите взад и вперед. Черт возьми, просто видя слова «зашифровать», «расшифровать» и «ключ» в потоке было бы достаточно, чтобы заинтересовать кого-то интересным для дальнейшего погружения (или получения прибыли ..). Не смотря на то, что открытое соединение неожиданно начинает передавать части зашифрованных пакетов и другие части в ясности.
Если то, что у вас есть, стоит зашифровать, тогда это стоит дополнительных $ 240 в год, чтобы сделать это правильно. Пожалуйста, отступите от уступа и просто сделайте это правильно.
Все настолько негативны, и, хотя я разделяю мнение, которое вы лично, вероятно, не должны делать, позвольте мне сделать несколько общих замечаний:
Для безопасного канала вам понадобятся три вещи:
Для шифрования вам необходимо реализовать шифр. Это выполнимо.
Обмен ключами является решающим моментом: оба сверстника должны знать, что они знают общий ключ, не имея возможности узнать общий ключ. Для этого существуют протоколы, и это должно быть возможно. SSL делает это, например. Тот факт, что вы можете обнюхать SSL-соединение и не узнать ничего, показывает, что это можно сделать.
Аутентификация необходима, чтобы остановить атаки «человек-в-середине», и для этого требуется какой-то внеполосный обмен информацией (например, телефонный звонок или инфраструктура PKI). Является ли все это на самом деле работает практически очень спорно, даже для SSL.
Таким образом, в принципе, если вы можете реализовать все эти компоненты через HTTP, тогда в принципе должно быть возможно запустить безопасную связь через HTTP. В конце концов, SSL делает то же самое, он запускает защищенный канал по небезопасной среде. В основном вы хотите реализовать SSL в JavaScript. Проверьте aSSL , они пробовали что-то подобное.
Мой совет – придерживаться SSL / TLS. Я думаю, что это упростит вашу жизнь, а также придаст вашему решению отрасли признанный авторитет.
Вместо статического IP-адреса вы можете использовать DynDNS (или аналогичную услугу) с самозаверяющим сертификатом?