Javascript + PHP шифрование с помощью pidCrypt - PullRequest
2 голосов
/ 30 августа 2011

Я работаю над попыткой реализовать механизм шифрования для передачи защищенной информации на мой сайт.Мой хост взимает дополнительную плату за 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);

Когда я ввожу «test» для значения для расшифровки, PHP показывает:1015 *

Таким образом, ни функции openssl_private_decrypt (), ни функции DecryptData2 () не будут правильно расшифровывать значения.EncryptData2 () и DecryptData2 () будут работать вместе, хотя.

Возможно ли, что я пропускаю что-то маленькое?Любой совет?

Редактировать: Вот команды, которые я использовал для создания ключей -

Это создает закрытый ключ:

 openssl genrsa -out private.pem 1024

Это создает открытый ключ:

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

Ответы [ 4 ]

2 голосов
/ 07 июня 2012

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

Используется библиотека 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);
}
?>

Наслаждайтесь!

1 голос
/ 13 июня 2012

Ваши расшифрованные значения имеют кодировку base64, поскольку pidCrypt использует кодировку base64 для обеспечения 8-битных символов до шифрования RSA. Так что просто base64-декодируй свои результаты.

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

0 голосов
/ 25 октября 2011

В итоге я использовал Open ID.Это небезопасно, но, по крайней мере, это немного лучше, чем ничего.Конкретная реализация, которую я нашел, была LightOpenID .

. Когда придет время обновлять, я выберу другой веб-хостинг, который позволит мне использовать SSL доступным способом.

Я так и не понял, почему мой код шифрования не работает.

0 голосов
/ 30 августа 2011

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

.прошлое и вывод всегда один и тот же.Это невозможно сделать каким-либо безопасным способом.

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

(примечание: расшифрованная строка - base64закодировано, попробуйте base64_decode )

...