Javascript+;使用pidCrypt的PHP加密

Javascript+;使用pidCrypt的PHP加密,javascript,php,encryption-asymmetric,pidcrypt,Javascript,Php,Encryption Asymmetric,Pidcrypt,我一直在努力实现一种加密机制,以便在我的网站上传递安全信息。我的主机收取额外的SSL费用,我还没有准备好承担额外的资金 我尝试使用javascript在客户端对值进行加密。然后,我尝试了几种在PHP端取消加密的技术。由于某种原因,数据被弄乱了 有人能指出我做错了什么吗?或者,我应该使用不同的javascript库进行加密吗?有什么建议吗 下面是javascript代码,它从页面上的输入提取要加密的文本,并从页面上的隐藏文本区域提取公钥 $(document).ready(function() {

我一直在努力实现一种加密机制,以便在我的网站上传递安全信息。我的主机收取额外的SSL费用,我还没有准备好承担额外的资金

我尝试使用javascript在客户端对值进行加密。然后,我尝试了几种在PHP端取消加密的技术。由于某种原因,数据被弄乱了

有人能指出我做错了什么吗?或者,我应该使用不同的javascript库进行加密吗?有什么建议吗

下面是javascript代码,它从页面上的输入提取要加密的文本,并从页面上的隐藏文本区域提取公钥

$(document).ready(function() {
  $('button').click(function() {
    var dataToSend = new Object();

    var input = $('input[name=textToEncrypt]').val();
    var public_key = $('textarea[name=publicKey]').val();
    var params = certParser(public_key);
        var key = pidCryptUtil.decodeBase64(params.b64);
    //new RSA instance
    var rsa = new pidCrypt.RSA();
    //RSA encryption
    //ASN1 parsing
    var asn = pidCrypt.ASN1.decode(pidCryptUtil.toByteArray(key));
    var tree = asn.toHexTree();
    //setting the public key for encryption
    rsa.setPublicKeyFromASN(tree);
    var t = new Date();  // timer
    crypted = rsa.encrypt(input);
    dataToSend.unencrypted = input;
    dataToSend.textToDecrypt = pidCryptUtil.fragment(pidCryptUtil.encodeBase64(pidCryptUtil.convertFromHex(crypted)),64);
    $('body').append(dataToSend.textToDecrypt);


    $.getJSON('engine.php', dataToSend, function(data) {
      var items = [];

      $.each(data, function(key, val) {
         items.push('<li id="' + key + '">' + key + ': ' + val + '</li>');
      });

      $('<ul/>', {
        'class': 'my-new-list',
        html: items.join('')
      }).appendTo('body');
    });


  });
});
这将创建公钥:

 openssl rsa -in private.pem -pubout > public.pem

您无法在客户端安全地加密任何内容。这是因为客户端可以完全控制将要发送的任何数据以及加密引擎

过去对此有过一些争论,结论总是一样的。这不能以任何安全的方式进行

你应该问自己的问题是:你在试图保护自己/你的客户免受什么伤害?
如果您试图保护自己不受人们嗅探线路或篡改请求数据的影响,唯一可行的解决方案是SSL。
如果说还有其他问题的话,加密技术并不是我们要寻找的解决方案


(另一方面,解密的字符串是base64编码的,试试看)

我最终使用了开放ID。它不安全,但至少比没有要好一点。我发现的具体实现是

我将选择一个不同的网络主机时,是时候更新,这将允许我使用一个负担得起的方式SSL


我一直不明白为什么我的加密代码不起作用。

试试下面这个简单的例子。我只使用它来加密密码,但您也可以在整个表单中使用它

它使用的是一个开源javascript库

HTML/JAVASCRIPT:

<script language="JavaScript" type="text/javascript" src="jsbn.js"></script>
<script language="JavaScript" type="text/javascript" src="rsa.js"></script>

<script language="JavaScript">

    function encryptData(){

        //Don't forget to escape the lines:
        var pem="-----BEGIN PUBLIC KEY-----\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfmlc2EgrdhvakQApmLCDOgP0n\
NERInBheMh7J/r5aU8PUAIpGXET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t\
6rF4sYqV5Lj9t32ELbh2VNbE/7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaA\
U8bTnLEPMNC1h3qcUQIDAQAB\
-----END PUBLIC KEY-----";

        var key = RSA.getPublicKey(pem);

        element=document.getElementById('password');
        element.value=RSA.encrypt(element.value, key);
    }
</script>

<form method='POST' id='txtAuth' onsubmit='encryptData()'>
    <input type='text' name='username'/>
    <input type='password' name='password' id='password' placeholder="password"/>
    <input name='submit' type='submit' value='Submit'>
</form>

函数encryptData(){
//别忘了逃过这一关:
var pem=“----开始公钥-----\
migfma0gcsqgsib3dqebaquaa4gnacbiqkbgqdfmlc2egrdhvakqapmlcdogp0n\
NERInBheMh7J/r5aU8PUAIpGXET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t\
6rF4sYqV5Lj9t32ELbh2VNbE/7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaA\
U8bTnLEPMNC1h3qcUQIDAQAB\
-----结束公钥------”;
var key=RSA.getPublicKey(pem);
元素=document.getElementById('password');
element.value=RSA.encrypt(element.value,key);
}
PHP:


您解密的值是base64编码的,因为pidCrypt使用base64编码来确保RSA加密之前的8位字符。因此,只需对结果进行base64解码即可


请参见

Crypto rule#1:不要使用自己的加密。@Alex无关-他在这里使用的是已建立的加密例程,而不是自己的加密例程。digitaleagle您确定公钥/私钥匹配,并且两个系统的格式都可用吗?(字节数组vs十进制vs十六进制vs base64等等)不要这样做。转储您的主机并获取一个支持SSL的主机。原因如下:@Rudu-我很确定钥匙是匹配的。我试图通过同时使用EncryptData()和DecryptData()函数来运行它。他们可以成功地加密和解密“测试”。也许我会尝试重新生成新钥匙,包括今晚我是如何做到的。@NullUserException-我正在认真考虑,但我的合同还有3个月左右。目前,我与Lunarpages合作。我注意到GoDaddy有一个包含SSL的计划,我想研究一下。在那之前,我只是想做些事情来降低风险。我希望如果我在餐馆或公共网络上连接,可以防止有人轻易查看用户名和密码等信息。我的想法是使用公钥/私钥,这样,如果他们嗅探网络,就无法轻松查看信息。我知道这对中间人的攻击是不安全的。如果他们写了一些东西把公钥从页面上取下来,他们就可以用自己的密钥来代替,这样就可以得到信息。如果他们写了一些东西来代替密钥,他们也可以修改脚本,把密码以明文形式发送给他们。老实说,你所尝试的是高尚的,但不会增加任何真正的安全感,只是默默无闻。如果你对此感到满意,那就去吧。只是不要自欺欺人地认为这不是(复杂的)烟雾和镜子。我不明白的是,为什么网络托管公司会宣传一款不包含SSL的博客产品?例如:此解决方案至少禁止某人在同一公共网络(即餐厅)上使用类似的工具,不是吗?除此之外,我的保护就是好的备份。我没有任何值得窃取的数据。或者我的想法不对?嗯,你用户的密码可能是最有价值的数据。(人们经常重复使用密码)所以是的,你可以防止明文密码被嗅探。但是,嗅探器不需要密码,他/她需要sessionId。此外,使用您选择的构造,嗅探加密密码并在以后重新发送它就像知道明文密码一样好。您正在尝试的内容已经被很多人(包括我)尝试了很多次,最终,SSL始终是唯一可行的选择。至于在整个表单中使用SSL,请记住,您需要一个大密钥来加密大量数据。一个1024位的密钥(使用速度很快)只加密117个字符的纯文本。因此,是的,可能用于表单数据,但仅当表单很小或单独加密每个字段时(可能是一个缓慢的过程)。
 openssl rsa -in private.pem -pubout > public.pem
<script language="JavaScript" type="text/javascript" src="jsbn.js"></script>
<script language="JavaScript" type="text/javascript" src="rsa.js"></script>

<script language="JavaScript">

    function encryptData(){

        //Don't forget to escape the lines:
        var pem="-----BEGIN PUBLIC KEY-----\
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDfmlc2EgrdhvakQApmLCDOgP0n\
NERInBheMh7J/r5aU8PUAIpGXET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t\
6rF4sYqV5Lj9t32ELbh2VNbE/7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaA\
U8bTnLEPMNC1h3qcUQIDAQAB\
-----END PUBLIC KEY-----";

        var key = RSA.getPublicKey(pem);

        element=document.getElementById('password');
        element.value=RSA.encrypt(element.value, key);
    }
</script>

<form method='POST' id='txtAuth' onsubmit='encryptData()'>
    <input type='text' name='username'/>
    <input type='password' name='password' id='password' placeholder="password"/>
    <input name='submit' type='submit' value='Submit'>
</form>
<?php

if (isset($_POST['password'])) {

    //Load private key:
    $private = "-----BEGIN RSA PRIVATE KEY-----
    MIICXAIBAAKBgQDfmlc2EgrdhvakQApmLCDOgP0nNERInBheMh7J/r5aU8PUAIpG
    XET/8+kOGI1dSYjoux80AuHvkWp1EeHfMwC/SZ9t6rF4sYqV5Lj9t32ELbh2VNbE
    /7QEVZnXRi5GdhozBZtS1gJHM2/Q+iToyh5dfTaAU8bTnLEPMNC1h3qcUQIDAQAB
    AoGAcbh6UFqewgnpGKIlZ89bpAsANVckv1T8I7QT6qGvyBrABut7Z8t3oEE5r1yX
    UPGcOtkoRniM1h276ex9VtoGr09sUn7duoLiEsp8aip7p7SB3X6XXWJ9K733co6C
    dpXotfO0zMnv8l3O9h4pHrrBkmWDBEKbUeuE9Zz7uy6mFAECQQDygylLjzX+2rvm
    FYd5ejSaLEeK17AiuT29LNPRHWLu6a0zl923299FCyHLasFgbeuLRCW0LMCs2SKE
    Y+cIWMSRAkEA7AnzWjby8j8efjvUwIWh/L5YJyWlSgYKlR0zdgKxxUy9+i1MGRkn
    m81NLYza4JLvb8/qjUtvw92Zcppxb7E7wQJAIuQWC+X12c30nLzaOfMIIGpgfKxd
    jhFivZX2f66frkn2fmbKIorCy7c3TIH2gn4uFmJenlaV/ghbe/q3oa7L0QJAFP19
    ipRAXpKGX6tqbAR2N0emBzUt0btfzYrfPKtYq7b7XfgRQFogT5aeOmLARCBM8qCG
    tzHyKnTWZH6ff9M/AQJBAIToUPachXPhDyOpDBcBliRNsowZcw4Yln8CnLqgS9H5
    Ya8iBJilFm2UlcXfpUOk9bhBTbgFp+Bv6BZ2Alag7pY=
    -----END RSA PRIVATE KEY-----";
    if (!$privateKey = openssl_pkey_get_private($private)) die('Loading Private Key failed');

    //Decrypt
    $decrypted_text = "";
    if (!openssl_private_decrypt(base64_decode($_POST['password']), $decrypted_text, $privateKey)) die('Failed to decrypt data');

    //Decrypted :) 
    var_dump($decrypted_text);

    //Free key
    openssl_free_key($privateKey);
}
?>