I have an app using HTML5 caching for an "offline mode". When the app is offline, data is stored via javascript in localStorage to be sent to the server when the app comes back "online". I would like to run some of this data through an encryption before sticking it in localStorage in a way that can only be decrypted on the server.
I was thinking that a public/private key would be the way to do this. Is that a reasonable way to go about things? Are there any good javascript libraries for handling this sort of thing client-side? Are there good ruby/rails libraries/gems for handling this server-side?
If you only want to encrypt data in localStorage, you can use public key cryptography. Don't generate the keys in JS, do it server side, and send the public key with the page. Unfortunately, I don't know any well tested and maintained crypto library in Javascript.
For the level of security you're aiming at (just a little layer to prevent the user from reading the data), you can choose whatever implementation you want.
On server side, you can use the OpenSSL gem with the class OpenSSL::PKey::RSA.
For anyone else reading this: Don't use Javascript crypto, it's bad!
For handling this client side, there is the handleStorage plugin for jQuery, which is really easy to use, but is GPL. If you cannot use that due to licensing issues, you can combine the jStorage jQuery plugin with the blowfish jQuery plugin.
Related
I have searched all over the internet for the last days and not found a single example without it saying it's not safe and the same thing everywhere.
But also couldn't find cases like my use case so I had to ask it for myself.
The scenario: I have a backend which on only some of the data it sends I need some sort of extra security so other people won't be using my api publicly, I have successfully used Laravel's Crypto for encryption on backend and CryptoJs for decryption on the frontend.
So my only problem is where to store my larave's key which is used for AES encryption and decryption on frontend.
What I have already tried (or thought of):
.env files, they get included in the bundle anyways so what's the point.
Any obfuscation sound to be pointless.
I probably should use WebCrypto (https://stackoverflow.com/a/24677597/10268067) but couldn't get anywhere with it. (I just heard of it).
I need some suggestions, even if there was a secure way of storing my encryption key, I don't think there is a way to do it directly so I have to request my api for this encryption key at some point but where? If I have a route specifically for this purpose I don't think the hackers are too stupid to find that, heck I can even find that with interception of the requests and responses!
So I basically have two problems:
How to request the server somehow randomly or in anyways that hackers can hardly ever find my encryption key in the requests.
How to save in on js side of browser securely, for instance I decided to use Secure Store for my mobile app's version of this exact problem, but on the web I'm so lost!
Just to be clear, encryption happens on the backend, decryption (with the same key) happens on the frontend.
I have a backend which on only some of the data it sends I need some sort of extra security so other people won't be using my api publicly
Cryptography is not the solution for this. Big companies use API tokens and refresh tokens in order to accomplish this.
The solution you are looking for is called refresh tokens used along with the API tokens.
I am building a service which is using a powerful client-side script to execute actions. All communications with a server are done via WebSockets. I am looking for a way to protect information which is transferring between server and client, so nobody with beginning/medium knowledge in Chrome debugging and HTTP scrapping can simply decode these data. The script itself will be deeply obfuscated.
I read there are some RSA libraries for javascript to encrypt/decrypt data, but I hear like RSA is old and slow and that's why I need someone's advice who is the guru in such things. I need for simple MIT library, no need for paid solutions and giant-sized packages.
I am looking for a way to protect information which is transferring between server and client,
That is SSL (https) for. There is no reason not to use SSL
so nobody with beginning/medium knowledge in Chrome debugging and HTTP scrapping can simply decode these data. The script itself will be deeply obfuscated.
Often it is not so effective. If data are user entered or displayed, there is no reason to encrypt them. If data are provided from the server and not to be displayed, you can encrypt the data properly on the server side.
client-side encryption is usually feasible if you want to store or resend data encrypted or signed to other systems.
Usually adding more complexity doesn't add security.
I read there are some RSA libraries for javascript to encrypt/decrypt data
Just search for some https://gist.github.com/jo/8619441 or there is CryptoWebAPI https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API
the issue is - are you sure you need RSA? How would you manage and exchange keys? How would you ensure key authenticity?
but I hear like RSA is old and slow
RSA is old and slow and yet used and secure (when implemented properly). RSA is used along other (symmetric) ciphers to ensure speed and effectiveness. It is called hybrid cryptosystem
There are two used asymetric systems, RSA and ECC. Regardless that using ssl will ensure confidentiality and integrity, in most of the cases you would need to really justify using RSA on the client side
I am searching for a way to clientside decode RSA respectively openssl encoded messages.
Idea:
Special data is only stored encrypted with a public key on the server so that nobody is able to see the real data - even in case of server hacks.
An admin in the adminforce then can "open" these files by transfering them to the browser and some javascript code will decode the data so that it'll never decrypted on the server, only on the secure clientside.
I really need it to be decoded direclty in the browser with custom javascript because these data has then to be used by some algorithms clientside in js.
Problem:
There seems to be no openssl library in javascript or i didn't find one yet. While there are several pure js implementation of RSA they only implement the plain RSA algorithm but, plain RSA is not secure to be used as a block cipher and has some attacks like "choosen plaintext attacks".
Does anybody know of an javascript implementation of openssl decoding, or a plugin for firefox/chrome which adds these features to the document? Or any other secure asymetric encryption that's built into javascript?
As I was pointing out in a comment to your question, the vector of attack you're envisaging (compromised server) implies that the JavaScript is likely to be compromised too, in which case the JavaScript code running on the client shouldn't be trusted anyway. (It would be quite easy to make the JavaScript send the deciphered data back to the server with an asynchronous request in the background: again, since the server would be under the attacker's control, there wouldn't be any need for tricks to circumvent same-origin policies there.)
I would suggest going down the route of a standalone application (such as Java WebStart), perhaps signed (with a private key that's not held on the server).
If you're still willing to go ahead with this sort of architecture, avoid releasing the user's private key into the JavaScript at all cost. This could compromise the user's private key, not just the encrypted data.
When you use a private key in your browser for SSL/TLS client-certificate authentication, the private key isn't exposed to any code used by the server. It's used by the browser for the handshake, and the server gets the certificate (which is public), but the private key doesn't go anywhere near what the HTML+JS code can see. (In fact, in OSX with Safari, the private key is used by the underlying SSL/TLS library, and not even exposed to the user process.)
The JavaScript libraries for RSA that I've seen require direct use of the private key, that is, they need to be able to use the private exponent directly. That's clearly not good if you're in a situation you can't trust the server.
Being able to use a private key within the browser for RSA operations, without letting the script get hold of the private material itself would require tighter integration with the browser, in particular, some API to sign and decipher that would use these functions directly in the browser's security mechanism, without exposing the private key material (overall, a similar approach to what PKCS#11 offers to applications using it).
As far as I'm aware, the current Mozilla crypto JavaScript API doesn't provide functions to decipher/sign using the browsers (it's only for certificate request and key generation). There seems to be plans to do this, though:
https://wiki.mozilla.org/Privacy/Features/DOMCryptAPISpec/Latest
http://mozilla.ddahl.com/domcrypt/demos/demo.html
On the IE plaform, CAPICOM should have been of interest, but it seems to be deprecated nowadays.
Encrpytion is complex and expensive - particularly assymetric encrpytion (in most cases the assymetric encryption is only used to encrypt a randomly generated symmetric algorithm key).
There are implementations of RSA (and probably other asymmetric algorithms in javascript) and in some cases, compatible implementations in other languages (usually C) - try google for specifics - but I'm not aware of any which handles x509 encryption. OTOH writing a java applet to do this would be trivial.
But why bother? From my understanding of what you've written, you'd get just as much functionality for a lot less effort by using a symmetric algorithm and never sending the key back to the server:
allow the user to enter some data in a web page
allow the user to enter an encryption key
encrypt the data using the key
send the encrypted data back to the server
provide a decryption page where the user can retrieve the encrypted content and enter the key
decrypt the contents
Instead of relying on web server to send you both the encrypted data & the associated JavaScript code to decrypt the data (which could be corrupted in case of a compromised server), you could only download the data from the web server & decrypt it with a standalone application or a webpage with JavaScript that does NOT come from the same webserver (could be from another server or a local file). This way there wouldn't be any responses returned to the originating server or the attacker.
The data kept on the server could be encrypted with a key that only you know about and can decrypt (AES or RSA), and server could only be for storage. For decryption, download data to a trusted local machine first, so you only you will have access to unencrypted data, of course for a very limited amount of time.
Check out this native implementation of TLS in JavaScript.
Here's a guide to enable Windows Subsystem for Linux in Win 10 to install
Bash, which comes with SSL. Check your version & get the latest.
think about this. if there is a server hack, the hacker will have access to your encrypted data and to all your site source code. including the one used to decrypt the data. and it can get those from the website interface in plain javascript by looking at the source of the page.
I know, it looks strange, but I need to sign some data on client-side using javascript only, no ajax backdoor to server-side openssl available. Could someone suggest some client-side solution to sign data using private key? Is it possible?
Thanks.
Found great signing tool. It implements RSA-SHA1 (works perfectly) and RSA-SHA256 (works strange), and allow both to generate signature using private key and to verify signature using certificate.
I've gone down the same road as you, you're probably better off implementing something like oAuth.
The problem with what you're proposing is that there's absolutely no reliable way of storing the private key on the client machine, nor of now securely getting the public key back to the server other than HTTPS (and if you're using HTTPS, what's the point of this?)
If you really want to continue, there are some implementations out there: http://shop-js.sourceforge.net/crypto2.htm
And you probably want something horribly annoying like PersistJS (http://pablotron.org/?cid=1557) to try and save the private key as long as possible.
The W3C Web Cryptography API may be able to help. Can I use indicates modern browsers now support it.
For additional digital signature support, look at GlobalSign/PKI.js
PKIjs is a pure JavaScript library implementing the formats that are
used in PKI applications (signing, encryption, certificate requests,
OCSP and TSP requests/responses). It is built on WebCrypto (Web
Cryptography API) and requires no plug-ins. http://pkijs.org
Web Crypto appears to be the answer. Here is a tutorial (not mine). As for the comment, if you are using https, why do you need signing - these are needed for two different purposes. In infosec lingo, the former gives confidentiality and the latter non-repudiation.
I need something like a cookie, but I specifically don't want it going back to the server. I call it a "client side session cookie" but any reasonable mechanism would be great.
Basically, I want to store some data encrypted on the server, and have the user type a password into the browser. The browser decrypts the data with the password (or creates and encrypts the data with the password) and the server stores only encrypted data. To keep the data secure on the server, the server should not store and should never receive the password. Ideally there should be a cookie session expiration to clean up.
Of course I need it be available on multiple pages as the user walks through the web site.
The best I can come up with is some sort of iframe mechanism to store the data in javascript variables, but that is ugly. Does anyone have any ideas how to implement something like this?
FWIW, the platform is ASP.NET, but I don't suppose that matters. It needs to support a broad range of browsers, including mobile.
In response to one answer below, let me clarify. My question is not how to achieve the crypto, that isn't a problem. The question is where to store the password so that it is persistent from page to page, but not beyond a session, and in such a way that the server doesn't see it.
You could use JavaScript's localStorage object. The Dive Into HTML5 ebook has an excellent chapter on it. I think the chapter also mentions some possible work-arounds for browsers which to don't support localStorage.
For what you are looking for I would say that javascript is the best you could do.
You can retrieve the encrypted data onto the server and decrypt it using javascript on the client side. No transmission of password, no secret for the user.
It depends which encryption algorithm you are using but there is libraries for that (for example Stanford Javascript Crypto Library)
(but I don't understand why are you talking about cookies)
If you are interested in the storage aspect rather than the cryptography aspect, perhaps you might consider Thomas Frank's session variables