2011-08-30 29 views
2

我一直在努力實現一種加密機制,以在我的網站上傳遞安全信息。我的主機爲SSL收取額外費用,我還沒有準備好額外的金錢承諾。Javascript + PHP使用pidCrypt加密

我試圖使用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 
+0

加密規則#1:不要推出自己的加密。 –

+0

@Alex Irrelevant-他在這裏使用已建立的加密程序,並沒有自己動手。 digitaleagle您確定公鑰/私鑰是否匹配並且對於兩個系統都是可用的格式? (字節數組vs十進制vs十六進制vs base64等) – Rudu

+0

不要這樣做。轉儲您的主機並獲得支持SSL的主機。這是爲什麼:http://stackoverflow.com/questions/3604582/which-attacks-are-possible-concerning-my-security-layer-concept/3604619#3604619 – NullUserException

回答

0

你不能安全地加密客戶端上的任何內容。這是因爲客戶端對以及加密引擎的任何數據都有控制權。

過去一直存在一些爭論,結論總是相同的。它不能以任何安全的方式完成。

你應該問自己的問題是:你想要保護自己/你的客戶是什麼?
如果您試圖保護自己免受人們嗅探線路或篡改請求數據,唯一可行的解​​決方案是SSL。
如果有其他事情,加密不是尋找的解決方案。

(上一個方面說明,所解密的字符串是base64編碼,嘗試base64_decode

+0

我希望阻止某人輕鬆查看諸如用戶名和密碼等內容,如果我在餐館或某個公共網絡連接的話。我的想法是使用公鑰/私鑰,以便如果他們嗅探網絡,他們將無法輕鬆看到信息。我知道這從中間人攻擊是不安全的。如果他們寫了一些東西將公鑰從頁面上拉出來,他們可以用自己的密鑰替代,並以這種方式獲取信息。 – digitaleagle

+0

如果他們寫了一些可以替代密鑰的東西,他們也可以修改腳本以純文本形式發送密碼。老實說,你所嘗試的是高尚的,但不會增加任何真正的安全,只是默默無聞。如果你滿足於此,繼續。只是不要自欺欺人地認爲它只是(複雜的)煙霧和鏡子。 – Jacco

+0

我不明白的是,爲什麼Web Hosting公司會宣傳一款面向未包含SSL的博主的產品?例如: http://www.lunarpages.com/web-hosting/basic-hosting/ – digitaleagle

0

我結束了使用開放式ID。這並不安全,但至少它比沒有好一點。我發現的具體實現是LightOpenID

我會選擇一個不同的網絡主機,當它是時間更新,這將允許我以負擔得起的方式使用SSL。

我從來沒有弄清楚爲什麼我的加密代碼不起作用。

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

享受!

+1

就整個表單而言,記住你需要一個大的密鑰來加密大量的數據。一個1024位密鑰 - 使用起來很快 - 僅加密純文本的117個字符。所以,是的,也許用於表單數據,但只有當你的表單很小或者你單獨加密每個字段時(可能是一個緩慢的過程)。 –