Альтернатива SSL - зашифруйте пароль с помощью JavaScript, отправьте в PHP для расшифровки - PullRequest
5 голосов
/ 20 апреля 2011

Я создаю веб-сайт, и мои способы оплаты будут Google Checkout и Paypal. Там будут ссылки / кнопки, которые будут перенаправлять пользователя на защищенные сайты Google / Paypal для обработки платежей. Это означает, что мне не нужны дополнительные затраты в размере 150 долларов США в год и сложность установки SSL-сертификатов для моего сайта.

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

Я думаю, это можно реализовать с помощью криптографии с открытым ключом. Допустим, процесс идет примерно так:

  1. Открытый ключ находится во внешнем файле JavaScript, закрытый ключ в PHP на сервере
  2. Пользователь вводит свое имя пользователя и пароль в форму и нажимает кнопку "Отправить"
  3. JavaScript запускается и шифрует пароль, сохраняя его обратно в текстовом поле
  4. Форма отправляется на сервер, а пароль расшифровывается с помощью PHP
  5. Простой текстовый пароль в PHP солится и затем хэшируется по сравнению с хэшем в базе данных.
  6. Возможен аналогичный процесс для функций регистрации / смены пароля.

Я думаю, что-то вроде RSA поможет. Но я охотился по сети за рабочей библиотекой JavaScript, чтобы сделать это, но ни одна не кажется совместимой с доступными библиотеками PHP. В любом случае, он должен генерировать набор ключей, совместимых с JavaScript и PHP.

Кто-нибудь знает реальное рабочее решение для этого? Если нет, как насчет того, чтобы написать что-то одно, то с открытым исходным кодом. К сожалению, написание кода шифрования / дешифрования довольно сложно, поэтому я не знаю точно, что делают существующие библиотеки и как их модифицировать, чтобы он работал. У меня уже есть защита для фиксации / захвата сессии, поэтому я не заинтересован в этом. Просто интересно зашифровать данные перед тем, как они попадут на веб-сервер.

NB. Пожалуйста, не публикуйте несколько ссылок на автономные библиотеки шифрования Javascript или PHP, я нашел их уже в Google. Это на самом деле не полезно. Что мне нужно, так это код для шифрования JavaScript и расшифровки PHP, который на самом деле гармонично работает для получения желаемого результата, описанного выше.

Также, если вы можете воздерживаться от публикации комментариев типа «просто используйте SSL». Я бы на самом деле хотел бы решить эту проблему, даже если это не лучшая практика, но, тем не менее, это было бы интересно.

Большое спасибо!

Ответы [ 6 ]

18 голосов
/ 20 апреля 2011

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

7 голосов
/ 20 апреля 2011

RSA является излишним; что вам, вероятно, нужно, это простой протокол «вызов-ответ». Например:

  • Создать случайное значение для одноразового номера; это помогает предотвратить повторные атаки.
  • Отправьте это значение nonce и соль пароля в браузер вместе с остальной частью формы входа.
    • Вы храните пароли в соленой и хешированной форме, верно?
  • Когда пользователь вводит пароль, необходимо, чтобы скрипт в форме вычислял и отправлял взамен хеш (хэш (пароль, соль), nonce).
  • Когда сервер получает отправку формы, он должен вычислить хеш (сохраненный пароль, nonce) и убедиться, что он равен переданному значению.
    • Сохранить значение nonce на сервере; не верьте клиенту, чтобы он вернул его вам, или ваша защита от повторного воспроизведения исчезла.

Слабым местом этой схемы является то, что хеши паролей в базе данных в некотором смысле эквивалентны паролям; хотя, вероятно, невозможно извлечь исходный пароль, использованный для создания этих хешей, знание хранимого хеша достаточно, чтобы выдать себя за пользователя на вашем сайте.

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

3 голосов
/ 20 апреля 2011

Во-первых, я не думаю, что это хорошая идея.Я нашел несколько примеров использования Google, которые могут быть полезны для вас (однако я не проверял их):

GPL Шифрование с открытым ключом JavaScript

RSA PublicТест шифрования ключа в JavaScript

Шифрование PGP в JavaScript

Пример алгоритма RSA в JavaScript

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

2 голосов
/ 11 августа 2011

http://www.jcryption.org/ - это комбинация, которую вы ищете.

1 голос
/ 20 апреля 2011

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

0 голосов
/ 15 июля 2015

Это код для ввода данных, а затем для шифрования содержимого с помощью java-скрипта. Весь код также доступен в github.Проблема долго работала. Я нашел решение. Просто импортируйте его в localhost.

<html>

<input type="text" id="code" name="code"/>
<input type="submit" name="submit" value="submit" onclick="return encryptCode();"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">
function rc4(key, str)
{
    var s = [], j = 0, x, res = '';
    for (var i = 0; i < 256; i++) 
    {
        s[i] = i;
    }
    for (i = 0; i < 256; i++) 
    {
        j = (j + s[i] + key.charCodeAt(i % key.length)) % 256;
        x = s[i];
        s[i] = s[j];
        s[j] = x;
    }
    i = 0;
    j = 0;
    for (var y = 0; y < str.length; y++) 
    {
        i = (i + 1) % 256;
        j = (j + s[i]) % 256;
        x = s[i];
        s[i] = s[j];
        s[j] = x;
        res += String.fromCharCode(str.charCodeAt(y) ^ s[(s[i] + s[j]) % 256]);
    }
    return res;
}

function encryptCode()
{
  var value = document.getElementById("code").value;
  var key = "secretKeyToProvide";  /*--Provide Your secret key here--*/
  var codeValue = rc4(key, value);
  var arr = {code:codeValue, Age:25};
  $.ajax({
                url: "response.php",
                type: "POST",
                data: JSON.stringify(arr),
                dataType: 'json',
                async: false,
                contentType: 'application/json; charset=utf-8',
                success: function(data) 
                {
                    alert(data);
                }
            });   
}
</script>
</html>

Теперь расшифруем код в php

<?php

function mb_chr($char) 
{
    return mb_convert_encoding('&#'.intval($char).';', 'UTF-8', 'HTML-ENTITIES');
}

function mb_ord($char)
{
    $result = unpack('N', mb_convert_encoding($char, 'UCS-4BE', 'UTF-8'));
    if (is_array($result) === true) 
    {
        return $result[1];
    }
        return ord($char);
}

function rc4($key, $str) 
{   
    if (extension_loaded('mbstring') === true) 
    {
        mb_language('Neutral');
        mb_internal_encoding('UTF-8');
        mb_detect_order(array('UTF-8', 'ISO-8859-15', 'ISO-8859-1', 'ASCII'));
    }
    $s = array();
    for ($i = 0; $i < 256; $i++)
    {
        $s[$i] = $i;
    }
    $j = 0;
    for ($i = 0; $i < 256; $i++)
    {
        $j = ($j + $s[$i] + mb_ord(mb_substr($key, $i % mb_strlen($key), 1))) % 256;
        $x = $s[$i];
        $s[$i] = $s[$j];
        $s[$j] = $x;
    }
    $i = 0;
    $j = 0;
    $res = '';
    for ($y = 0; $y < mb_strlen($str); $y++)
    {
        $i = ($i + 1) % 256;
        $j = ($j + $s[$i]) % 256;
        $x = $s[$i];
        $s[$i] = $s[$j];
        $s[$j] = $x;
        $res .= mb_chr(mb_ord(mb_substr($str, $y, 1)) ^ $s[($s[$i] + $s[$j]) % 256]);
    }
    return $res;
}

$request_body = file_get_contents('php://input');
$json = json_decode($request_body);
$secretCode =$json->code ;
$age =$json->Age  ;
$key = "secretKeyToProvide";  /*--Provide Your secret key here what you have given in javascript--*/
$decryptedSecretCode  = rc4($key, $secretCode) ;
echo $decryptedSecretCode;
exit;
?>
...