2

Web サイトで安全な情報を渡すための暗号化メカニズムの実装に取り​​組んでいます。私のホストは 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 に次のように表示されます。

そのため、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

pidCrypt は base64 エンコードを使用して RSA 暗号化の前に 8 ビット文字を保証するため、復号化された値は base64 エンコードされます。結果を base64 でデコードするだけです。

https://sourceforge.net/projects/pidcrypt/forums/forum/923749/topic/3153476を参照してください。

于 2012-06-13T07:36:04.257 に答える
0

クライアント側で安全に暗号化することはできません。これは、暗号化エンジンだけでなく、送信されるすべてのデータをクライアントが完全に制御できるためです。

これについては過去にいくつかの議論がありましたが、結論は常に同じです。安全な方法では実行できません。

自問すべき質問は次のとおりです。自分自身やクライアントを何から守ろうとしていますか?
ネットワークを傍受したり、要求データを改ざんしたりする人から身を守ろうとする場合、実行可能な唯一の解決策は SSL です。
それ以外の場合、暗号は探すべきソリューションではありません.

(ちなみに、復号化された文字列は base64 でエンコードされています。base64_decodeを試してください)

于 2011-08-30T17:55:15.833 に答える
0

結局、Open ID を使用することになりました。安全ではありませんが、少なくとも何もないよりはましです。私が見つけた特定の実装はLightOpenID でした。

更新する時期になったら、手頃な価格で SSL を使用できる別の Web ホストを選択します。

暗号化コードが機能しない理由がわかりませんでした。

于 2011-10-24T21:19:08.913 に答える