Я сделал это. Я использую это асимметричное шифрование RSA на стороне клиента JavaScript, чтобы предотвратить отправку учетных данных для входа в виде простого текста по HTTP.
Цель состоит в том, чтобы предотвратить атаки воспроизведения запросов входа, основанные на сниффинге сети. Конечно, это не так безопасно, как HTTPS, поскольку оно не противостоит атакам типа «человек посередине», но может быть достаточным для локальных сетей.
Клиентское шифрование использует превосходную работу Трэвиса Тридвелла , основанную на JSBN . Веб-страница Travis также может генерировать закрытые и открытые ключи RSA (если вам лень использовать openssl
). Ключи генерируются в формате PCS PKCS # 1. Я шифрую username+password+timeInMs+timezone
, чтобы зашифрованный контент изменялся при каждом входе в систему.
На стороне сервера мой код Java прочитал чтение PEM-файла PKCS # 1, используя Apache JMeter's org.apache.jmeter.protocol.oauth.sampler.PrivateKeyReader
:
PrivateKey pk = (new PrivateKeyReader("myPrivateKeyFile.pem")).getPrivateKey();
Затем я расшифровываю зашифрованный контент, используя
byte[] enc = DatatypeConverter.parseBase64Binary(clientData);
Cipher rsa = Cipher.getInstance("RSA");
rsa.init(Cipher.DECRYPT_MODE, pk);
byte[] dec = rsa.doFinal(enc);
String out = new String(dec, "UTF8");
Затем я проверяю, соответствуют ли временная метка / часовой пояс на стороне клиента серверной временной метке / часовой пояс. Если задержка составляет менее нескольких секунд, процесс входа в систему продолжается. В противном случае запрос считается повторной атакой, и вход в систему завершается неудачно.