It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I know everyone uses TLS/SSL as transport layer security on the web.
What would prevent me from generating let's say keypair manually, encrypting data client-side (using JS for example) with that public key and submitting that data to my server with http's GET/POST request?
I mean - I can just use JS library to encrypt some form data with that public key - right?
Only person who has private key can decrypt it - right? And private key would be kept on the server of course. No key warning will pop up - since transmission is a regular http request. So why I need TLS?
How do you trust that the Javascript delivered to the browser is the Javascript that will encrypt with the correct key?
Think about it for a second, and realize that security best practices are very subtle and nuanced and simply slapping encryption on top is not a solution.
Also, if you're dealing with the "key popup", you've broken one leg of the TLS trust model (the trusted certificate authority) by using an unsigned server certificate.
Let's give an example of how this could go wrong. Let's say that what you're trying to encrypt is some form data and send it to the server. The server sends it's public key to the client to encrypt with. The client in JavaScript encrypts this data and sends it to the server. Assuming that's what happened you'd be okay.
Now let's explore how this could go wrong. With the status of switching and the like these days it is fairly hard to sniff someone else's packets without access to the hardware. Therefore, most of the cases you are trying to avoid also allow the attacker to present a man in the middle attack. In this case the attacker could provide the client with whatever JavaScript they pleased. A clandestine way of stealing data would be to provide JavaScript that does everything that the original JavaScript does, and the also sends the unencrypted data to another server.
This can happen in a similar fashion for data from the server being sent to the client.
P.S. If your problem is the lack of a CA signed cert, I would suggest getting a free one from http://www.startssl.com/
You are correct. You can do that, and you'll have utilized strong cryptography, which is in fact one of the underlying components of SSL/TLS.
One of the issues is that computing that for every piece of data is computationally expensive. You also need to have cross compatible libraries on the client and server that handle the encryption/decryption process.
However, you will have lost any transparency in your web application because you now have to perform this encryption process on every piece of data you need to keep secret.
TLS is session oriented, so this is not an apples to apples comparison. What TLS is doing is setting up an encrypted session that is transparent to the client and server. It's making an encrypted pipe and allowing data to flow through it. It also has baked in concepts of "Trust" and identity, so that a client can have some indication that the information they are sending is going to the person they think it is.
What you are describing is taking pieces of data, encrypting them, then sending the encrypted version, and requiring decryption on the other side prior to use. Your scheme can and will work if you want to go through the pain of getting it setup, but what have you gained? Furthermore, since your scheme will have none of the things that TLS has in preventing man in the middle attacks, it's susceptible to those problems in a number of ways -- from someone injecting their own library and key into the client so that your app starts sending data to them instead of you, or that they get between you and the client, and send data to you that your server believes is coming directly from them and is instead coming from the attacker.
Digital certificates include the public key of the subject, digitally signed by the CA using their private key. Your browser contains certificates identifying their public keys (signed, in the case of root certificates, with the same private key) and this allows your browser, assuming it trusts the pre-installed CA certificates, to verify your identity. When you access a server, the server-side certificate is used to transmit the server's public key to your browser, which it then uses to encrypt the initial exchange of credentials. When client-side certificates are required, similar considerations allow the server to identify you.
There's nothing to stop you using your public key in a JS library to encrypt data, but how is the server supposed to decrypt it? Passing it your private key negates the purpose of the private key, which is to ensure that only you can decrypt information encrypted with your public key. So the correct way to proceed would be to encrypt with your private key, but then anyone who has your pubic key can decrypt it (this technique is usually used for digital signature).
Really you should use the server's public key to encrypt your transmission, and let it use its private key to decrypt it. The whole business of secure key exchange is very subtle, and there are many examples (from IBM downwards) of companies and people developing their own encryption systems, relying on privacy of the algorithm. They have always proved to be relatively easy to break. Best not to design your own system until you have a little more security experience ...
Your question makes no sense.
If you generate a key pair and encrypt with the public key, only you can decrypt that message. So sending it to someone else is futile. You could encrypt with the server's public key, but then you have the problem of establishing exactly what that is, securely.
And then the server has no way to encrypt data back to you, unless it uses your public key, in which case it has the same problem of authenticating your identity that you already had as the client.
TLS/SSL solves those problems, and a few others you haven't thought of yet.
Related
I am working on an application who's front end is in javascript (backbone) and backend in codeigniter(php). I want a way where I can encrypt a message in backend using a secret key and decrypt that message from javascript using same secret key. Basically I need this flow for user authentication.
Its turning out to be a hard luck as I am not able to find such a combination over internet. What way can be used for this workflow?
Thanks
using HTTPS is pretty much the only answer that makes sense. Relying on Javascript cryptography is bad because malicious users can do all sorts of nasty stuff to inject scripts to make your front end instead send passwords out in plaintext, or send them to a server controlled by the attackers.
HTTPS and SSL/TLS has it's problems, but it is the standard mechanism for securing web application communication channels. It has been reviewed extensively by experts in the field, and has been secured against various failure modes and attack scenarios.
For instance: It sounds like in your comment that you are going to use a single static key for your encryption. Since you need to send the key to the client, how are you going to do this securely? What prevents a user from getting the key legitimately by visiting your login page, then using it to decrypt the communications of any other users? What about when enough messages have been sent with one key, what is your mechanism for moving to a new key?
These sorts of scenarios are covered by HTTPS. You might have to pay a few bucks for a certificate if you are doing something "real" with your webapp (and it really is just a few bucks these days), but it is really the way to go.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
This is more of a software engineering question than a programming one. I tried to make the title as relevant as possible, if someone feels they can word it more appropriately please let me know.
So, I have been developing an instant chat web service using asynch. javascript and PHP. The main selling point behind the application is utmost secrecy. There are many instant chat apps out there, from Live Messenger, Yahoo Messenger, IRC and Skype, to name a few. However - call me paranoid - but I felt like I could never trust the companies behind the software as very little control is exposed to the user and most seem to neglect privacy issues altogether. I'm aware there are many other secure/private IM apps, but decided to create my own, it uses SSL to encrypt communication between all points of use (user->database->user), the to/from properties within the message table are SHA256 hashed with a salt and as a further precaution messages are automatically deleted from the database as soon as the recipient receives (or requests I should say) the message.
At the moment the messages themselves are left plain text. I could use PHP's various encryption libraries but how would I do so in a way that would remove the potential for myself, the owner, to decrypt messages thus compromising privacy?
I would by no means do this of course, I would just like to prove privacy to this extent. If I were to encrypt with a password, I would know the password. If I were to encrypt with a programmatic password, I would know where PHP would store the password.
Is there a way to solve this? Or does this just end with trust?
UPDATE: As far as I'm aware PHP is stateless, but sessions for example force the server to store data in memory, could this be a solution to have the key/password stored in the memory?
Thanks for any ideas or advice.
The typical way this type of problem is solved is with public key encryption. You can read here for an overview: http://en.wikipedia.org/wiki/Public-key_cryptography.
In a nutshell, every user is issued a public key/private key combination. The public key is public so you can get anyone's public key. The private key is kept only by the user that it belongs to. The key to public key cryptography is the math that allows one to encrypt something using the public key, but only decrypt it with the private key. So you can obtain someone's public key, encrypt a message destined for them and they are the only ones that can decrypt it with their private key.
In your scheme, public keys can be kept on your server and requested by the client. Public keys are available to anyone. In a browser-only environment, it's a challenge to store a private key. It could be stored in local storage, but then it can only be used from that particular computer. If you allow it to be stored on your server so the user can retrieve their private key no matter where they are, then you're back to the same problem you originally have (you have to trust the server and the server author that they aren't accessing the private key themselves).
There's a more complicated algorithm that tries to cache the public key/private key (probably in local storage), but anytime it is not available any more (like when the user switches computers), you simply coin a new one and store that locally and update the directory with the new public key. This has the advantage that you can continue to use the system from a new computer, but the disadvantage that you won't be able to read messages encrypted with a prior public key unless you somehow have the private key that corresponds with that public key. So, this could work in a live instant messaging scenario where messages are never saved on the server for you, but not work if the server holds messages for you and you are expected to be able to read them from any location, each with their own key pair.
SSL solves this issue by using dynamically generated public key / private key pairs but they are negotiated and exchanged in a direct end-to-end connection (so there is no node in the middle that gets to see or store unencrypted data) so another possibility would be to use peer-to-peer gaming technology (which has it's own warts and may not be possible in only a browser) to create a peer-to-peer connection and use SSL over that connection to either exchange security credentials (outside the view of you and your server) or to just directly exchange the messages. Your server would be used to facilitate two endpoints connection and communicating that desire, but not used for the exchange of security information.
You could do the encryption on the client. If you want utmost privacy, then you don't trust ANYTHING on the server. If the message and/or decryption keys never hit the server, then you essentially can't read the message even if you're tempted to do so.
Of course, now you've got a new problem - how to exchange decryption keys between two or more of your clients without involving your server.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I would like to encrypt data that travels back and forth between the server and client in my Web application. I would use SSL but that requires a certificate along with a dedicated IP address. I have no problem getting a certificate but the dedicated IP requires me to upgrade to a business hosting plan which is $20 a month on my Web host. I have no plans on doing that as I'm sticking with my $20/year shared hosting plan.
So, I would like to implement an alternative to SSL. It does more than SSL does, though. Along with encrypting the data sent back and forth, it also encrypts the rows in the database. I was thinking of doing something like this:
JavaScript Code:
var transfer_key = 'whatever';
function encrypt(data, key) {...}
function decrypt(data, key) {...}
function send_data_to_server(url, data)
{
$.post(url, {'data' : encrypt(data, transfer_key) }, function(response) {
var decrypted_response = JSON.parse(decrypt(response));
});
}
PHP Code:
$data = $_POST['data'];
$transfer_key = 'whatever';
$storage_key = 'whatever2';
function encrypt($data, $key) {...}
function decrypt($data, $key) {...}
databaseQuery('INSERT INTO table VALUES (?)', encrypt($data, $storage_key));
$decrypted_data = decrypt($data, $transfer_key);
$response = processData($decrypted_data);
echo encrypt($transfer_key, $response);
As you can see, the data the client sends to the server is encrypted, and vice versa. And the data in the database is encrypted as well. Now of course, I would never implement the keys like that. I would probably have a second or third key that's randomly generated for each user. So transfer_key could be equal to a constant_key concatenated with a random key, and same goes for storage_key.
Would this be a good alternative to SSL?
How can I implement this type of encryption in such a way that it is harder to defeat? Are there any particular weaknesses to this approach?
I'm probably going to find a JavaScript library that takes care of the encryption and use PHP's mcrypt extension for the server-side. I was thinking of Blowfish, maybe AES256, but I'm not sure which one gives me the best ratio of encryption strength to memory consumption.
Advice?
Uh, oh. Good luck with that. Have you had a look at the TLS specification? Do you think you can come up with something adequate that will be tested by millions of people?
No, really, TLS has been tested and improved over the years by so many people, cryptographers who do nothing else than breaking such protocols, it would be a hard task coming up with something adequate.
SSL has been developed by experts in the field and they most certainly thought at first, too, that their protocol was absolutely unbreakable. But then there was version 2, then 3, then TLS v.1, v1.1 and now 1.2.
If you don't have any prior experience in designing secure protocols you should stick with the mainstream and use TLS/SSL.
Security is one of the rare fields where it makes sense and is actually cool to go with the mainstream, so I'd say the added money would be well spent.
Edit:
Maybe I was a bit harsh, and I lacked some explanation as to why your approach cannot compete with a somewhat complex protocol such as TLS, so let's analyze it:
How would you do the key exchange? For AES to work on both ends, you need to do a Key Exchange, for symmetric encryption, both parties need to possess the same key. As you said, you would like to generate it randomly on the client - so far so good. First problem - you need to generate a secure random number - otherwise, e.g. by using the built-in Javascript random number generator - attackers would be able to predict your random numbers after some time.
Let's say you got that mastered. Then the next problem arises, how would you send this key to the server in a secure manner, i.e. perform the key exchange? There you will need some form of authentication on the server side, otherwise just about anyone could impose as your server and do this:
trick people into sending their keys to their rogue server first
then forward the key to your server
your server would dutifully send the data encrypted with the established key
the attackers would intercept that data and happily read your secrets by decrypting with the key they just stole
So you need server authentication, at least, if not client authentication, too. This will imply that you need some form of asymmetric/public key cryptography to encrypt/wrap the key with the server's public key so that just the server is able to decrypt it.
Once you mastered that, you are still susceptible to more involved forms of attacks such as replay attacks, man-in-the-middle-attacks, reflection attacks, ...
Maybe you also want Perfect Forward Secrecy so that once a key does get compromised the attacker would not be capable of decrypting any past data. You will need Diffie-Hellman (preferably in its Elliptic Curve Cryptography form) to achieve this.
Last but not least, a session mechanism would probably also be nice so that you can pick up previous sessions with already established symmetric keys, so that you can reduce the load on the server by not having to re-establish it again using the somewhat resource-intensive public key algorithms.
-> Add a couple more features, such as securely negotiating an algorithm suite that both client and server acknowledge to support and you will have reimplemented the TLS protocol.
Sorry if this sounds a bit sarcastic, but I know it seems tempting to roll your own crypto schemes (it's fun, too), but in the end you should stick with TLS: it's (relatively) easy to use, it runs on the transport layer (so you can code your applications as if there were no encryption at all) and best of all, it's secure.
EDIT: Well, there have been some attacks recently, but almost all attacks exploited the "human factor" in these protocols by attacking the public key certificates that back the protocol (Comodo, DigiNotar etc. are prominent examples) or more arcane features of the protocol like algorithm negotiation etc., but the BEAST has been the first time that TLS has been successfully attacked on the cryptography level, which is interesting and scary at the same time, because the basics of that attack have been known for some years now.
Still, with recent fixes for BEAST in place by now, I would bet that TLS is still the best option you have for secure communication on the web, especially when compared to hand-crafted solutions.
Ryan: I'm saying this in what I hope is the best possible way: memory consumption is the absolute least of your problems.
There is nothing secure about this. Nothing. N.o.t.h.i.n.g.
It's dead from the very first sending of that javascript... I don't care how long your keys are or how random the salt is.
What you have won't stop someone sitting in a coffee shop with their laptop open grabbing packets from intercepting the keys and being able to easily decrypt everything else you pass back and forth. Heck, just seeing the words "encrypt", "decrypt", and "key" in the stream would be enough to pique someones interest to dive further for fun (or profit..). Never mind watching an open connection suddenly start transferring parts of the packets encrypted and other parts in the clear.
If what you have is worth encrypting then it's worth the additional $240/year to do it right. Please, step back from the ledge and just do it right.
Everyone is being so negative, and while I share the sentiment that you personally should probably not be doing this, let me make some general remarks:
For a secure channel you need three things:
line encryption
key exchange
authentication
For encryption, you need to implement a cipher. That's doable.
Key exchange is the crucial point: Both peers need to know that they know a common key without anyone else being able to know the common key. There exist protocols for that, and it should be possible to implement that. SSL is doing that, for example. The fact that you can sniff an SSL connection and not learn anything shows that it can be done.
Authentication is necessary to stop man-in-the-middle attacks, and this requires some sort of out-of-band information exchange (like a phone call or PKI infrastructure). Whether any of this really works practically is highly debatable, even for SSL.
So basically if you can implement all those components over HTTP, then in principle it should be possible to run secure communication over HTTP. After all, SSL is doing the same thing, it's running a secure channel over an insecure medium. Basically what you want is to implement SSL in JavaScript. Check out aSSL, they've tried something like that.
My advice is to stick with SSL/TLS. I think this will make your life easier and also give your solution industry recognized credibility.
Instead of the static IP address, could you use DynDNS (or similar service) with a self-signed certificate?
I'm trying to make a "normal" username/password login form secure, without needing HTTPS. My idea is this:
Server generates a keypair for some kind of assymetric encryption algorithm. It stores this keypair in a temporary table of sorts (or perhaps the local session data).
Server sends the form to the client and includes the public key.
User fills in the form.
Before it's sent to the server, Javascript encrypts the password using the given public key.
Form is sent.
Server decrypts the password with it's private key (which it gets from the temporary table, using the public key to find it).
What I need to know for this is:
Which encryption method is the best to use? RSA?
How can I decrypt the password in PHP?
And probably the most difficult one, how can I make Javascript encrypt the password?
In advance: I'm sorry for being negative, however;
Implementing your own security protocol is never a good idea, unless you're a highly trained security expert, or you actually don't really care about the security and only want to create an impression of security (marketing) and stop the script kiddies.
SSL is definitely not a fingerprint lock, as so say in your comments, JCryption and your proposal are equal to having a door where you can enter a two-digit code to open the door and you have infinite many retries. It's hard to break if you're not really interested and just passing by, but if you want to get in that house (and you probably do, else security wouldn't be needed), you will get in.
Another point is that people often forget to mention what they want to achieve. Security has the famous three components called CIA, namely confidentiality, integrity and availability. Is it for you important that the data you transport is confidential, or is integrity important (i.e. you're sure that the sent data comes from the one you expect and not the man in the middle)?
To make it concrete in this case, the only thing that you achieve here is that a passive attacker cannot see whats passing by on the line. As soon as your attacker gets active and changes the messages on their route, your whole security falls apart. So my advice would be to just stick with the solution the experts have come up with (TLS in this case, not ssl since that is the old version of it) and just make sure your server supports it.
edit:
Btw, SSL/TLS cannot work without certificates. The whole point in public key crypto is that there should be at least somewhere some trusted party.
On the other hand, if you don't care that your users will get an "invalid certificate" message, you can just create your own certificate which is really easy. In that case your certificate isn't trusted by the browsers, however, you can be sure that at least your communication is safe (okay, there are exceptions in this case, but still ...)
The argument that certificates should be for free is really from a perspective point of view. I think people who claim it is bogus/idiotic don't know what it takes to be a certification authority. These companies invest millions in order to keep the communication secure, and sure they make nice money out of selling certificates, but hey its their job and they also deserve to make money, just like any others.
edit2: after comments
I indeed say that you have a secure communication. However, you miss the point that with self signed certificates you dont know to whom you talk securely. Imagine a dark room which is completely isolated from eavesdropping a conversation. Now imagine the difference between such a room with and without light. If the room has light, you can actually see to whom you're talking securely and only choose to talk to people you like to trust. Now imagine doing the same in a completely dark room. You can only hope that the guy you talk to inside this dark room is just an ally and not your adversary. However, you cannot know that, just hope that it's ok. And although your conversation itself is secure, nobody can listen in, you still dont have "full" security.
If I, being a crook, do a man-in-the-middle attack, I can create a self signed certificate without the user noticing. So the advantage of using TLS with self signed certificates is that you have at least the implementation of the protocol corrent (and even implementing this is far from easy). Moreover you can avoid the ugly warnings by advising your users to manually trust the certificate once. However, this is only possible if you have a relatively small group of returning visitors, for a public website this is not really a solution.
This doesn't seem that secure from the perspective of the client. Two (related) problems:
How does the client trust the server? How can it verify that the key the sever's presenting is the one that belongs to it?
It's possible to do man-in-the-middle attacks. A malicious proxy could strip out and store the public key before the client sees it, substituting its own, then decrypt the password when the client authenticates, store it, and re-encrypt and send the response on so the client doesn't realise something's up.
What's wrong with ordinary SSL? There has to be a consensus that it's secure, otherwise vendors and organisations would drop support for it overnight. By contrast, most attempts to invent a funky new way to do security "on the cheap" usually miss something fundamental.
It looks like a lot of what you want to do is supplied by the jquery plugin JCryption. It even assumes PHP as the backend, so a good fit for you.
Livejournal does something similar to what you want where:
Server generates a challenge string, inserts this into form. [1]
Client generates response by MD5 hashing the password, then MD5 hashing the previous hash with the challenge prepended [2].
Server gets response, checks challenge validity, then does same as step 2, comparing the result to the response.
This is a very good idea, and it's already been done. See jCryption.
jCryption looks interesting, I've not seen it before.
But I have to ask what is wrong with SSL?
Encryption code is notoriously hard to do right, and you can bet that the SSL implementations found in browsers and http servers are much more rigorously tested and reviewed than the jCryption stuff.
That said, jCryption looks neat if you absolutely need to avoid SSL, and you're not dealing with super-sensitive information.
By storing the passwords in encrypted method on the server the server can retrieve the passwords and verify checksum sent by client. Send a session password and ask client to make a hash of session password and the user inputted password, do the same on the server and compare the two hashes.
This will not secure users from MITM attacks - local admins, NSA, telecom, router hijacks, but it will keep the password safe in open wlan.
I am interested in having something that I encrypt using a public key on a LAMPhp server, decrypted using the appropriate private key on the web client (firefox at least, best if it is standard javascript)
Note that what I want to do is -not- merely to have an encrypted connection using SSL/https. Or even to use browser-based client certificates as a login/access control method. I know how to do both of those things. What I want to do is more like emailing with gpg keys. I want to be able to create a short message that I will encrypt with a users public key that -only they- can decrypt using their private key. What I am looking for is not the privacy achieved automatically by ssl, but the ability to allow only particular users to decrypt messages. I know I can easily do this with gpg or perhaps SMIME, and perhaps that is the best way, but I would prefer a web-based alternative.
Firefox etc have a certificate stores, and I know that the private keys held there are unlikely to be exportable into javascript for obvious security reasons, but I would assume there is some way to -use- the certificates from javascript calls to decrypt something..
The reason I would like to do this, is that I need a secure method to give a randomly generated password to a particluar administrator. I am trying to implement full database translucency and public key cryptography seems like an important part of that effort. But this is one use-case that I am having trouble addressing without this kind of ability.
So on the php side I would use the openssl encryption calls like so...
<?php
$browsers_public_key = get_it_from_the_browser_via_apache_maybe();
openssl_public_encrypt($data,$encrypted_ends_up_here,$browsers_public_key);
echo "<html><head>
<script type='javascript'>
function decrypt_textarea(){
??
}
</script>
</head>
<body><textarea id='decrypt_me'> $encrypted_ends_up_here </textarea>
<div id='where_the_plaintext_goes'> </div>
</body> </html>";
?>
Note that I have found via stackedoverflow many fine javascript encrypton libraries... but I actually want to use keys imported into Firefox as per MyOpenId.com or CaCert.org
Does anyone know if this is possible?
Thanks,
-FT
It's been a while since you asked this question, but if you or anyone else is looking for a potential solution to this problem or a similar one, they should check out the JavaScript Forge project:
http://github.com/digitalbazaar/forge/blob/master/README
This project has an SSL implementation in JavaScript that will allow you to include a client-side certificate when communicating with Apache. You can also manually do RSA decryption using the associated private key (which you have access to in JavaScript).
For instance, the JavaScript could get/post to the server and include its client-side certificate. Apache could read this certificate, use the public key to encrypt whatever data is appropriate, and then return that data to the client. The client could then use its private key (in JavaScript) and decrypt the information and do something with it. This extra encryption is probably not even be necessary, however, if your server can authenticate the client-side certificate as the appropriate recipient of the secret you're trying to pass.
The Forge project also has the APIs to build a system for importing/exporting keys and certificates to/from Firefox or other browsers (if this is still a requirement for some reason). A little help from openssl might be necessary to get the keys/certs in the correct format for import/export (pem => pkcs12), but an example of how some of this works can be found in a JavaScript-based demonstration of WebID. WebID is a client-side certificate-based authentication system:
WebID management demo: https://webid.digitalbazaar.com/manage/
WebID authentication demo: https://payswarm.com/webid-demo/
Note that the SSL certificates for the above sites are self-signed and will require temporary exceptions to be added to your browser to view them. The sites do not require you to enter any personal information, they are for demonstration purposes only. However, if you go to the first link, you can generate keys in-browser (it uses Forge JavaScript to do this) and then you can see the private key and certificate that were generated, in PEM format, in the list at the top of the page. The key and certificate are persisted via Flash local storage.
Nearly 100% (if not that) of the source for the WebID management site is viewable since it is mostly JavaScript. Also, the Forge project itself (see the github link) is opensource.
Now that I understand what you're saying, I can give you a firm answer :)
The best I can tell you is that you can't get decent encryption in the way you're looking to do it. Private key encryption (namely RSA) uses very, very, very large numbers to do encryption. Using small numbers is very simple to crack computationally (there are only so many prime numbers) and the numbers get big extraordinarily quickly. Basically, with RSA, you need to take large numbers and raise them to large exponents. JavaScript is able to support quite large numbers, but you'll hit a wall with performance. With a 512-bit key, encryption of a few kilobytes can take up to a few seconds, while decryption can take seconds to minutes to do. The reason JS is so slow is simply because it's not a compiled language. Sure, you could decrease the key size, but anything larger than a couple kilobytes and you've got a problem.
Also, RSA is inherently insecure in a web page because the private key is transmitted alongside the data to be decrypted (unless it was transferred earlier), which enables anyone that receives the page to decrypt the data.
I'm going to assume that you're looking to do this because you want to obfuscate some code from your user or a client, so I'm going to recommend that you check out XOR encryption. Granted, it's nowhere near as secure as RSA, but it uses principles that can be very secure if used properly. For instance, if you use a random key that's used only once and has the same length as your data/code (an one-time pad), your encryption is "uncrackable". Even better, XOR encryption is FAST. Here are some resources:
http://guymal.com/mycode/xor_js_encryption/
http://javascript.internet.com/passwords/xor-encryption4.html
Hope you have luck with what you're trying to do!
I am searching exactly the same thing you do and wanted to use php's openssl-functions, too.
I was happy to see that on the phpside everything was working great with private/public key (encrypt/decrypt) and now wanted to find a way to use privatekey on clientside as you do.
!!!
IF you will find anything please let me know by email:
pki (at) life.de
!!!
And for the performance aspect:
You would encrypt the big parts with symetric encryption and only the decryption key with the public key of the client to excahnge it. So you dont't need to enrypt many kb.
But it seems to be an dead end with firefox, but with IE and ActiveX it seems possible with
CAPICOM (I had not much read about it now).
hxxp://geekswithblogs.net/shahed/archive/2007/05/03/112232.aspx
But for JavaScript/PHP have a look at (and read all comments at FAQ and other pages,too!In future maybe bidirectional communication was mentioned):
hxxp://www.jcryption.org/
hxxp://www.zend.com//code/codex.php?ozid=1323&single=1
Pure Javascript Public/Privatekey encryption
hxxp://shop-js.sourceforge.net/crypto2.htm
A helful FireFox-Addon for PKI:
hxxps://addons.mozilla.org/en-US/firefox/addon/4471
hxxp://www.mozilla.org/projects/security/pki/nss/tools/index.html
PHP with OpenSSL on Serverside / .NET on CLientside
hxxp://www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html
Javascript OpenPGP
hxxp://www.hanewin.net/encrypt/
PS: stupid mechanism prevents me posting links ...
You don't handle SSL in your PHP. SSL is handled by the web server automatically. If you're using Apache, here's a simple tutorial:
http://www.debian-administration.org/article/Setting_up_an_SSL_server_with_Apache2
The idea is that you write your code like normal, and when the user accesses your site using https, the server automatically encrypts the connection. On the client side, the browser is capable of using the private keys that it already has to automagically decrypt the connection and present the code to the user agent.
Hope this helps!