2

我一直在努力尝试实施一种加密机制,以便在我的网站上传递安全信息。我的主机对 SSL 收取额外费用,我还没有准备好接受额外的金钱承诺。

我尝试使用pidCrypt通过 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');
    });


  });
});

这是我应该解密该值的 engine.php 代码。请注意,我从不同的示例中尝试了几种不同的方法。

<?php
   require_once 'private/keys.php';



function EncryptData($source)
{
  /*
   * NOTE:  Here you use the $pub_key value (converted, I guess)
   */
  $key = $DEkeys->pubKey;
  openssl_public_encrypt($source,$crypttext,$key);
  return(base64_encode($crypttext));
}

function DecryptData($source)
{
  /*
   * NOTE:  Here you use the returned resource value
   */
  $decoded_source = base64_decode($source);
  openssl_private_decrypt($decoded_source,$newsource,$DEkeys->privKey);
  return($newsource);
}

function EncryptData2($source)
{
  $fp=fopen("/pathtokey/public.pem","r");
  $pub_key=fread($fp,8192);
  fclose($fp);
  openssl_get_publickey($pub_key);
  /*
   * NOTE:  Here you use the $pub_key value (converted, I guess)
   */
  openssl_public_encrypt($source,$crypttext,$pub_key);
  return(base64_encode($crypttext));
}

function DecryptData2($source)
{
  #print("number : $number");
  $fp=fopen("/pathtokey/private.pem","r");
  $priv_key=fread($fp,8192);
  fclose($fp);
  // $passphrase is required if your key is encoded (suggested)
  $res = openssl_get_privatekey($priv_key);
  /*
   * NOTE:  Here you use the returned resource value
   */
  $decoded_source = base64_decode($source);
  openssl_private_decrypt($decoded_source,$newsource,$res);
  return($newsource);
}

$out = new stdClass;

$out->hello = 'hello, world!';

if(!empty($_GET["textToDecrypt"])) {
   $out->raw = $_GET['textToDecrypt'];
   $out->unencrypted = $_GET['unencrypted'];
     if($DEkeys->privKey == false) {
       $out->error = 'Could not read private key';
     }
     $out->success = openssl_private_decrypt(base64_decode($out->raw), $decrypted, $DEkeys->privKey);
     $out->decrypted = $decrypted;
     $out->dec2 = DecryptData2($out->raw);
     $out->test1 = EncryptData2('testing');
     $out->test2 = DecryptData2($out->test1);
} else {
   $out->nondata = $_GET['textToDecrypt'];
}


echo json_encode($out);

当我为要解密的值输入“测试”时,PHP 显示: - 已解密:dGVzdA== - dec2:dGVzdA==

因此,openssl_private_decrypt() 和 DecryptData2() 函数都不会正确解密这些值。EncryptData2() 和 DecryptData2() 将一起工作。

有没有可能我错过了一些小东西?有什么建议吗?

编辑:这是我用来创建密钥的命令——

这将创建私钥:

 openssl genrsa -out private.pem 1024

这将创建公钥:

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

4 回答 4

2

试试下面这个简单的例子。我只用它来加密密码,但你也可以将它用于整个表单。

它使用开源的 javascript 库https://github.com/ziyan/javascript-rsa

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>

PHP:

<?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);
}
?>

享受!

于 2012-06-06T21:19:31.837 回答
1

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

https://sourceforge.net/projects/pidcrypt/forums/forum/923749/topic/3153476

于 2012-06-13T07:36:04.257 回答
0

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

当需要更新时,我将选择一个不同的网络主机,这将使我能够以负担得起的方式使用 SSL。

我从来没有弄清楚为什么我的加密代码不起作用。

于 2011-10-24T21:19:08.913 回答
0

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

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

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

(附带说明,解密的字符串是 base64 编码的,请尝试base64_decode

于 2011-08-30T17:55:15.833 回答