68860

Javascript + PHP Encryption with pidCrypt

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

Answer1:

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!

Answer2:

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

Answer3:

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.

<sub>(on a side note, the decrypted string is base64 encoded, try base64_decode)</sub>

Answer4:

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.

Recommend

  • Python: open with .Cer file to get public key and then perform verification
  • Build Git server
  • Hybrid cryptography. Length of the data to decrypt is invalid
  • php session not working after publish on web hosting
  • Upload file using PHP from Compute Engine to Cloud Storage
  • Whats the best way of persisting data to Isolated Storage on Windows Phone 7?
  • Find unique tuples in a relation represented by a BDD
  • Is it possible to create a self-extracting archive which will run a specific file when unzipped?
  • Base Internationalization and “Could not find a storyboard named […]”
  • UITableView takes much longer to load when numberOfRows returns a large number
  • How to remove single character words from string with preg_replace
  • Displaying a list of videos from a channel - Vimeo Advanced API
  • PHP Listener Script for Paypal Webhooks
  • Javascript/Jquery runs fast in desktop browsers, but slow in mobile/smartphone browsers…should I spl
  • Salesforce Different WSDL files and when to use
  • Python pickle not one-to-one: different pickles give same object
  • SAVE attribute needed for Fortran variables when only the C_LOC address is returned to a C program?
  • Do I need to seed any random number generator before using EVP_PKEY_keygen of OpenSSL?
  • Array with custom indexes in Ionic2
  • Tamper-proof configuration files in .NET?
  • QLineEdit password safety
  • Nant, Vault & Windows Integrated Authentication
  • Counter field in MS Access, how to generate?
  • output of program is not same as passed argument
  • Check if a string to interpolate provides expected placeholders
  • Validaiting emails with Net.Mail MailAddress
  • Which linear programming package should I use for high numbers of constraints and “warm starts” [clo
  • Javascript + PHP Encryption with pidCrypt
  • Websockets service method fails during R startup
  • Apache 2.4 - remove | delete | uninstall
  • WOWZA + RTMP + HTML5 Playback?
  • VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '
  • Why can't I rebase on to an ancestor of source changesets if on a different branch?
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • Getting Messege Twice Using IMvxMessenger
  • How does Linux kernel interrupt the application?
  • Qt: Run a script BEFORE make
  • How can i traverse a binary tree from right to left in java?
  • Conditional In-Line CSS for IE and Others?
  • How can I use threading to 'tick' a timer to be accessed by other threads?