2016-07-27 3 views
0

У меня есть приложение для Android, которое подключается к серверному рельсу. Я хочу зашифровать данные, которые я отправляю между устройствами и сервером. Я использую базовое шифрование с секретным ключом. Ключ на самом деле не секрет, поскольку я храню его на apk, и поэтому он легко разбирается с использованием методов декомпиляции обратной инженерии и apk.Является ли это «достойным» методом шифрования?

В результате я создал секретный ключ, основанный на пароле пользователя. Ключ должен иметь фиксированную длину и видеть, как заставить пользователей использовать сверхдлинные пароли, это не вариант, что я делаю, это добавить символы (в основном те, которые я использовал в своем старом закодированном ключе), поэтому строка (пароль + символы) имеет требуемую длину. Затем я шифрую все параметры (я использую JSON для связи между сервером и клиентом), кроме имени пользователя (которое технически не должно быть зашифровано, поэтому это не имеет большого значения). Когда запрос JSON достигает сервера, я использую параметр имени пользователя, чтобы захватить пароль пользователя из базы данных (на основе сервера), а затем, создав ключ, мне нужно «дешифровать/зашифровать» данные, которые я получаю/отправка. Таким образом, ключ всегда один и тот же между сервером/клиентом, но он уникален для каждого пользователя, и таким образом мне не нужно хранить простой в использовании, жесткий код в моем APK. Кроме того, пароль не сохраняется в устройстве, пользователи должны вводить пароль каждый раз, когда они хотят войти на сервер.

Что я хочу знать, может ли этот подход считаться «прилично обеспеченным»?

+0

Являются ли имена пользователей уникальными? Если нет, использование имени пользователя для извлечения пароля вызовет проблемы, если у вас есть несколько экземпляров одного и того же имени использования. Кроме того, что произойдет, если пользователь изменит свой пароль? Затем вы заново шифруете все данные (при условии, что они зашифрованы в покое, то есть)? – Tim

+0

Да, имена пользователей уникальны. –

+3

Почему бы просто не использовать https? – nasch

ответ

1

Вы должны попытаться просмотреть https://en.m.wikipedia.org/wiki/RSA_(cryptosystem). Вы используете открытый ключ (хранящийся в приложении) для шифрования данных, а затем сервер использует закрытый ключ (хранящийся на сервере) для дешифрования данных. Используя RSA, вы не можете блокировать пакет с помощью открытого ключа, а только шифровать его. Так что это безопасно. Вы должны создать пару ключей (или набор ключей) для каждого клиента.

+0

Это может помешать атакам MITM, я думаю, но злоумышленник может получить открытый ключ и отправить запрос, и сервер не будет знать, что это было от злоумышленника. Будь то проблема, зависит от ОП. – nasch

+0

Если подлинность является проблемой, тогда запрос должен быть подписан с помощью закрытого ключа. –

+0

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

1

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

Другой подход заключается в извлечении ключей шифрования во время выполнения и их хранении в Android Keystore. Доступ к Android Keystore намного труднее для злоумышленников для доступа к ключам. Также этот подход не требует, чтобы пользователи вводили свои пароли каждый раз, когда они используют приложение. Однако при первом обмене симметричным ключом этот подход зависит от MitM attack. Чтобы решить эту проблему, вы должны сначала использовать асимметричные криптографические схемы для безопасного обмена симметричным ключом, тогда вы всегда можете использовать ключ, хранящийся в хранилище ключей.

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

Однако, на мой взгляд, лучший подход заключается в использовании решения TLS. В TLS для согласования предварительно разделенного ключа (т. Е. Симметричного ключа) используется алгоритм RSA, тогда все трафики шифруются/дешифруются с использованием симметричных алгоритмов.

0

Вы всегда можете использовать алгоритм ключ выведения на основе пароля, если вы хотите: https://en.wikipedia.org/wiki/PBKDF2

Дело думать, однако, является то, будет ли ваш ключ график вращения автоматически будет совпадать с графиком ротации пароля.

0

Вам просто нужен клиент и сервер, чтобы иметь тот же симметричный ключ, основанный на некотором «пароле», правильно? Почему бы просто не получить ключ от пароля на каждом конце.

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

Затем клиент отправляет счет соли и итераций в ясность на сервер. Сервер просматривает свою копию пароля (при условии, что вы храните пароль, а не хэш), а с солью и итерациями генерирует соответствующий симметричный ключ.

Уникальная соль для каждого соединения затрудняет подготовку набора предварительно полученных ключей, чтобы попытаться, а высокий счетчик итераций несет огромную временную стоимость для совершения атаки словаря на сервер (т. Е. Пытается использовать количество паролей hugh).

Смежные вопросы