views:

890

answers:

2

I recently found this RSA JavaScript library: http://www.ohdave.com/rsa/. However, it requires that the key be pre-generated. Here are my questions/issues:

  1. I'd like to generate an RSA keypair in the JavaScript (so that I don't have to change the code every time I want a new keypair.)

  2. While I understand how this can be used to send secure data, if I'm not mistaken this library cannot be used for the client to receive secure data from the server (because the public and private exponents, and the modulus, are transmitted plain-text from the server). Am I mistaken?

I'd love some discussion about this. I'm no security expert, but I have a pretty firm grasp on asymmetric encryption.

A: 

I'm not a security expert either, but here are my thoughts:

  1. You can't generate the keypair in Javascript on the client size, since you want the receiver (the server) to know the private key, and client to only know the public key. You could expose a RESTful URI that gives you a new public key on each request, but the client and server will need to know which key pair is being used (which could be stored in some session state). Alternatively the server could generate a new pair every N seconds to avoid this overhead. AFAIK, you shouldn't really need to generate new pairs if your keys are of sufficient length, and a lot of secure sites renew their keys every N years only.

  2. If you look at the library closely, the one function, encryptedString(key, s), only uses key.e and key.m (via key.barret). I.e. you only need to send these two variables in plain text in order to encrypt your data. You can keep key.d private on the server side. So you can use the code to send data securely, just not in its current form...

bjnortier
1. You are talking about sending *from* the client *to* the server. I agree that this can be done with this javascript RSA library. However, I am talking about the *client* receiving information from the server.2. Yes, the client only needs to know the public key to *send* secure data.
B T
+2  A: 

Generating the keypair requires a strong random number generator (I don't think you have one in JavaScript), and quite a bit of computation (for primality testing). Then once you have your pair, when you transmit your public key up to the other side, there's an opportunity for man-in-the-middle attack since there is no integrity check on the public key transmission.

You will get secure transmission to whoever has the private key. It's not clear from your question whether that is the client or the server. You can initialize a shared secret by having whoever has only the public key generate a shared secret, encrypt it and send it to whoever has the public key.

You can get a similar feature set (dependence on random number generator, vulnerability to MITM, ability to create shared secret for use as session key) but with much less computation by performing a Diffie-Hellman key exchange instead.

You are probably better off figuring out how to configure SSL on your server.

Liudvikas Bukys
The Diffie-Hellman key exchange sounds interesting, I'll look into that. Heres a link I found to a javascript implimentation: http://enanocms.org/News:Article/2008/02/20/Diffie_Hellman_key_exchange_implementedOn the point of assymetric key pairs, a strong random number generator could be ported pretty easily from another language. Same with primality testing. I don't think this would be entirely time-prohibitive in javascript, especially with the right background thread runing it (while a user uses the rest of the page). Do you know of any good C-style RSA key generation code i could use?
B T
I hear that Simson Garfinkel's book on PGP has a pretty good explanation of the code including the primality tester - using various fast methods then doing some final passes with code based on Fermat's Little Theorem. And you should be able to finding it in some old PGP source or any of the OpenPGP or gpg implementations. But I think you will find that it's too slow running in Javascript.
Liudvikas Bukys