5

我正在建立一个网站,我的付款方式将是 Google Checkout 和 Paypal。会有链接/按钮将用户重定向到安全的 Google/Paypal 网站以处理付款。这意味着我不需要每年 150 美元的额外费用和为我的站点安装 SSL 证书的复杂性。

但是,我想在用户登录时加密用户的密码,这样如果他们在网络上,一些运行 FireSheep 等的恶意人员在发送到服务器时无法读取用户的实际密码。该站点的其余部分不需要加密,因为它不是真正的敏感数据,并且可能会显着降低用户体验。

我的想法是这可以用公钥加密来实现。可以说这个过程是这样的:

  1. 公钥在 JavaScript 外部文件中,私钥在服务器上的 PHP 中
  2. 用户在表单中输入他们的用户名和密码并点击提交
  3. JavaScript 运行并加密密码,将其存储回文本字段中
  4. 表单提交到服务器,密码用PHP解密
  5. PHP 中的纯文本密码经过加盐和哈希处理,然后与数据库中的哈希值进行比较。
  6. 注册/更改密码功能可能类似的过程。

我在想像 RSA 这样的东西可以解决问题。但是我在网上搜寻了一个可以工作的 JavaScript 库来做这件事,但似乎没有一个与可用的 PHP 库兼容。无论如何,它需要生成一组与 JavaScript 和 PHP 兼容的密钥。

有人知道这个的实际工作解决方案吗?如果不是,我们写一个怎么样,然后开源它。不幸的是,编写加密/解密代码非常复杂,所以我真的不知道现有库在做什么以及如何修改它们以使其工作。我已经对会话固定/劫持提供了保护,所以我对此不感兴趣。只是对在数据到达 Web 服务器之前对其进行加密感兴趣。

注意:请不要发布一堆指向独立 Javascript 或 PHP 加密库的链接,我已经在 Google 上找到了这些链接。这实际上没有用。我需要的是用于 JavaScript 加密和 PHP 解密的代码,它们实际上可以和谐地协同工作以产生上述预期结果。

另外,如果您可以避免发布诸如“仅使用 SSL”之类的评论。我实际上想要一个解决这个确切问题的方法,即使它不是最佳实践,它仍然会很有趣。

非常感谢!

4

6 回答 6

18

只有一个问题:攻击者不需要知道实际密码。他需要看到的只是发送到服务器的值。该值允许用户登录。该值是什么无关紧要;无论是明文、加密文本还是猫的图片。它只是一个对用户进行身份验证的令牌。如果攻击者可以看到此令牌并重复相同的请求,并且相同的请求允许他登录,那么您将一无所获。

于 2011-04-20T01:45:36.157 回答
7

RSA 太过分了;您可能需要的是一个简单的质询-响应协议。例如:

  • 生成一个随机nonce值;这有助于防止重放攻击。
  • 将该 nonce 值和密码 salt 与登录表单的其余部分一起发送到浏览器。
    • 您正在以加盐和散列的形式存储密码,对吗?
  • 当用户输入密码时,让表单上的脚本计算并发送回 hash(hash(password, salt), nonce) 代替。
  • 当服务器收到表单提交时,让它计算 hash(storedSaltedPassword, nonce) 并验证它是否等于提交的值。
    • 在服务器上保留 nonce 值;不要相信客户端会将其回显给您,否则您的重播保护已经消失。

这种方案的弱点是数据库中的密码散列在某种意义上是密码等效的;虽然提取用于生成这些哈希的原始密码可能是不可行的,但了解存储的哈希足以在您的站点上冒充用户。

SSL 证书的用途完全不同:SSL 证书的目的是使第三方流氓服务器难以声称是您的服务器,因为它没有由某个相互信任的第三方签署的证书。属于您的域。另一方面,如果您无法阻止流氓服务器冒充您的服务器,那么您就无法保护您的用户不向该流氓服务器提供密码,尽管有密码学。

于 2011-04-20T01:48:50.213 回答
3

首先,我认为这不是一个好主意。我使用 Google 找到了一些可能对您有用的示例(但是我没有测试过这些示例):

GPL JavaScript 公钥加密

JavaScript 中的 RSA 公钥加密测试

JavaScript 中的 PGP 加密

JavaScript 中的 RSA 算法示例

您应该建立一些加盐机制来为每个加密值加盐,否则密钥可能会受到损害。

于 2011-04-20T01:43:18.143 回答
2

http://www.jcryption.org/ -- 是您正在寻找的组合。

于 2011-08-11T09:35:39.593 回答
1

您不需要加密密码。您需要对密码进行哈希处理。您真的真的不想自己访问明文密码,否则您将失去不可否认性,这会产生严重的法律后果。在继续之前,您需要彻底调查此含义。

于 2011-04-20T12:24:19.187 回答
0

这是获取输入然后通过java脚本加密内容的代码整个代码也可以在github中找到。你们可以搜索它encrypt_js_decrypt_php。问题一直存在。我想出了解决方案。只需将其导入本地主机。

<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;
?>
于 2015-07-15T07:29:04.577 回答