# Is javascript RSA signing safe?

I'm currently working on a secure open source messaging system (https://github.com/DSMNET/DSMNET). Currently I'm using the cryptico.js (https://github.com/wwwtyro/cryptico) library to encrypt all the messages sent.

Now to authenticate user's my server will send a random string and the client will encrypt the string and sign it. The server will check if the signature matches the publickey stored for the user. User's will generate their public and private key with their password.

I would like to know if using javascript RSA and using RSA signatures to authenticate is safe or can people forge RSA signatures.
Thanks

-
Are you using HTTPS? Without HTTPS a webapplication has no hope of being secure. –  CodesInChaos Sep 6 '13 at 12:02
The data goes over Web Sockets. –  C1D Sep 6 '13 at 12:02
It still matters if your website was loaded over SSL (i.e. uses HTTPS) and if the web sockets run over SSL. –  CodesInChaos Sep 6 '13 at 12:04
The client is a .html file meaning you can run it locally and I am still working on adding SSL for the web sockets. EDIT: Are you suggesting that more than SSL is not needed. –  C1D Sep 6 '13 at 12:07
The point that @CodesInChaos is making is that the javascript source code itself (and not just the user data) needs to be downloaded by the client over HTTPS, otherwise it can be modified in transit to behave in a malicious way. Read this before proceeding. –  hunter Sep 6 '13 at 12:17

If you implemented it well, and there is no MITM (i.e. use authenticated comm channel), then it is difficult to forge the RSA signatures (meaning you can use them safely).
However, in your implementation there are 2 other major factors that you need to consider: One is the use of Javascript as a coding medium: there are many who consider Javascript to be a bad languange to use for writing security code due to some notable exposure to adversaries. I personally am not in that camp - if you take good care of securing your environment where you run the JS code you will be OK.
Also, there are some advantages of letting the user's browser do the work (and Java has its own set of implementation / management problems), this may be a prudent choice.

The second point is a major one: you selected cryptico engine, and we don't know how well the guy who wrote and modified the code behaved. Some critical security routines there were modified by him, and this should ring a big red alarm bell over its usage. If you plan to use it for anything important, you need to pass the published code through a critical security/cryptographic review before usage. You might also want to consult these comments: http://blog.thedod.iriscouch.com/6b99948869ce0ec3a2e6a51da3c281a9

-
JavaScript usually does not have a trust store. You may not have a secure random generator either, generally a requirement to perform encryption. Downloading the application has security drawbacks even if SSL is deployed. There are few - if any - trustworthy crypto libraries for JavaScript. It runs slow and dynamic typing makes it very easy to make mistakes. –  owlstead Sep 6 '13 at 22:42
All those negatives may or may not be practically meaningful - depending upon the application and environment. The Stanford's SJCL is a reasonable implementation, including the Fortuna-based RNG (granted that, since JS can't access system params as native apps do, the available entropy pool is not as strong, but it is still reasonable for practical use). If you download the code not as embedded in HTML page but as a packaged file to run locally (with a hash fingerprint), then I would consider it trustworthy. To fend off mistakes, need to run some test vectors during code review. –  Ninveh Sep 7 '13 at 0:47
Thanks for that. I will have a look at using Java for encryption. I will also see if there are any other RSA library's created by more trusted members in the community. –  C1D Sep 7 '13 at 5:56
Later JavaScript engines may be able to access an entropy source, but I don't think the use is widespread just yet. Random numbers are required for almost any crypto. SJCL is the implementation that is maintained by a single person (who just quit, fortunately somebody else has taken over). The first time I used it I found out that it forgot to take any of the AAD into account when generating the authentication tag (using the convenience library). SJCL has come from a university paper that focuses on JavaScript performance. –  owlstead Sep 7 '13 at 16:17

RSA on itself is never safe! You must use proper functions to handle padding and probabilistic signing correctly. Otherwise your protocol is vulnerable to a bunch of attacks. PKCS #1 defines secure and well established algorithms like RSAES-OAEP and RSASSA-PSS. RSA without a padding or signature scheme is like using a block cipher in ECB mode.

JavaScript RSA implementations may be vulnerable to side channel attacks, too. Timing analysis attacks are a serious issue. Your code's run time must never depend on input from an untrustworthy source. However it's nearly impossible to know how a JavaScript engine is optimizing your code. There are just too many browsers with too many different versions and implementation of JS engines.

A very simple approach for constant run time uses sleep to archive constant time (pseudo code):

runtime = 2 seconds # twice as long as the slowest machine
start = time()
do_rsa()
end = time()
sleepduration = sleeptime + start - end
if sleeptime < 0:
error()
sleep(sleepduration)


Please don't fall for the temptation to do sleep(random()). It's not safe.

-