В первой части статьи обсуждалась ситуация, когда для защиты трафика мы по каким-либо причинам не можем использовать https. При этом, передаваемый в открытом виде пароль становится легкой добычей мошенников. Предложенный в статье метод позволял избавится от угрозы перехваты пароля или от кражи БД хэшей паролей, но был бессилен перед злоумышленником, который и БД владеет и контролирует трафик. Предлагаемый ниже метод безопаснее, но сложнее.
Одним из достоинств алгоритма аутентификации, описанного в первой части статьи, была возможность внедрить его в уже существующие сервисы прозрачно для пользователя. Данное решение сделать этого не позволяет, так как в БД сервера хранятся уже не хэши паролей, а ключи RSA. Выбор асимметричной криптографии обусловлен возможностью хранить в БД информацию (публичный ключ), раскрытие которой не несет угрозу паролю. Наиболее распространенный сегодня размер ключа RSA 1024 bit. Запомнить такой ключ и вводить его вручную нереально. Что бы избежать этого приватный ключ, также хранится на сервере, но в зашифрованном виде. Ключ шифрования генерируется на основании пароля пользователя. Это конечно «костыль», но при использовании пароля в качестве секрета, этот «костыль» неизбежен.
Процесс регистрации выглядит следующим образом:

Процесс аутентификации выглядит следующим образом:

Снова прилагается демонстрация и исходные коды. В подготовке примера использовались библиотека AES Chrisa Veness, библиотека RSA jCryption и библиотека RSA написанная студентами Стэнфорда.
Надеюсь, еще одно, уже более «красивое» решение, я опишу в следующей статье.
UPD: Как и обещал — habrahabr.ru/blogs/web_security/120990
Одним из достоинств алгоритма аутентификации, описанного в первой части статьи, была возможность внедрить его в уже существующие сервисы прозрачно для пользователя. Данное решение сделать этого не позволяет, так как в БД сервера хранятся уже не хэши паролей, а ключи RSA. Выбор асимметричной криптографии обусловлен возможностью хранить в БД информацию (публичный ключ), раскрытие которой не несет угрозу паролю. Наиболее распространенный сегодня размер ключа RSA 1024 bit. Запомнить такой ключ и вводить его вручную нереально. Что бы избежать этого приватный ключ, также хранится на сервере, но в зашифрованном виде. Ключ шифрования генерируется на основании пароля пользователя. Это конечно «костыль», но при использовании пароля в качестве секрета, этот «костыль» неизбежен.
Процесс регистрации выглядит следующим образом:
- Клиент выбирает себе логин и пароль;
- Клиент генерирует ключевую пару RSA. Открытый ключ e,N и закрытый ключ d,N;
- Закрытый ключ d,N шифруется AES используя ключ k на базе пароля;
- Клиент отсылает на сервер, а сервер сохраняет — логин, открытый ключ e,N и закрытый ключ d,N зашифрованный на ключе k.

Процесс аутентификации выглядит следующим образом:
- Клиент отсылает на сервер логин;
- Сервер отсылает клиенту случайное число RND зашифрованное открытым ключом e,N и зашифрованный закрытый ключ клиента d,N;
- Клиент вводит пароль, формируя тем самым ключ k и расшифровывая им свой закрытый ключ d,N;
- C помощью ключа d,N клиент расшифровывает RND и отсылает на сервер hash(RND);
- Сервер сравнивает полученный hash с hash(RND) сформированным на сервере.

Снова прилагается демонстрация и исходные коды. В подготовке примера использовались библиотека AES Chrisa Veness, библиотека RSA jCryption и библиотека RSA написанная студентами Стэнфорда.
Надеюсь, еще одно, уже более «красивое» решение, я опишу в следующей статье.
UPD: Как и обещал — habrahabr.ru/blogs/web_security/120990