JavaScript +使用 pidCrypt 进行 PHP 加密

发布于 2024-12-01 22:05:57 字数 4037 浏览 0 评论 0原文

我一直致力于尝试实现一种加密机制,以便在我的网站上传递安全信息。我的主机对 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 显示: - 解密:dGVzdA== - dec2: dGVzdA==

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

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

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

这将创建私钥:

 openssl genrsa -out private.pem 1024

这将创建公钥:

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

I have been working on trying to implement an encryption mechanism for passing secure information on my website. My host charges extra for SSL, and I am not ready for the extra monetary commitment.

I tried to use pidCrypt to encrypt the values on the client side via javascript. Then, I have tried several techniques for unencrypting on the PHP side. For some reason, the data just gets garbled.

Can someone point out what I am doing wrong? Or, should I use a different javascript library for the encryption? Any advice?

Here's the javascript code that pulls the text to encrypt from an input on the page and the public key from a hidden text area on the page.

$(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');
    });


  });
});

This is my engine.php code that is supposed to decrypt the value. Notice that I have tried several different ways from different examples.

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

When I enter "test" for the value to decrypt, the PHP shows:
- decrypted: dGVzdA==
- dec2: dGVzdA==

So, neither the openssl_private_decrypt() nor the DecryptData2() functions will correctly decrypt the values. The EncryptData2() and DecryptData2() will work together though.

Is it possible I am missing something small? Any advice?

Edit: Here are the commands I used to create the keys --

This creates the private key:

 openssl genrsa -out private.pem 1024

This creates the public key:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

痕至 2024-12-08 22:05:57

尝试以下简单示例。我仅使用它来加密密码,但您也可以将它用于整个表单。

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

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

享受吧!

Try the following simple example. I used it only to encrypt a password but you could use it for the whole form as well.

It is using a open source javascript library 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);
}
?>

Enjoy!

So要识趣 2024-12-08 22:05:57

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

请参阅https://sourceforge.net/projects/pidcrypt/forums/forum/ 923749/主题/3153476

Your decrypted values are base64 encoded because pidCrypt uses base64 encoding to ensure 8 bit characters prior to RSA encryption. So simply base64-decode your results.

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

温柔戏命师 2024-12-08 22:05:57

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

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

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

(顺便说一句,解密的字符串是base64编码的,尝试base64_decode

You cannot securely encrypt anything on the client side. This is because the client has full control over any data that will be send, as well as the crypto engine.

There has been some debate about this in the past, and the conclusion is always the same. It cannot be done in any secure manner.

The question you should ask yourself is: what are you trying to protect yourself/your clients from?
If you try to protect yourself from people sniffing the wire or tampering with the request-data, the only viable solution is SSL.
If anything else, crypto is not the solution to look for.

(on a side note, the decrypted string is base64 encoded, try base64_decode)

要走就滚别墨迹 2024-12-08 22:05:57

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

当需要续订时,我将选择不同的网络主机,这将使我能够以经济实惠的方式使用 SSL。

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

I ended up using Open ID. It's not secure, but at least it is a little better than nothing. The specific implementation that I found was LightOpenID.

I will be choosing a different web host when it is time to renew that will allow me to use SSL in an affordable fashion.

I never did figure out why my encryption code would not work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文