What are the scenarios which using Cryptography in JavaScript could make sense? - javascript

My friend has an idea about protecting the stored cookies in browser with adding an encryption on them using library such as Stanford Javascript Crypto Library.
Meanwhile i believe such actions are not possible because, javascript has no access to file system.
The question is:
what would be the functionality the said library?
What does it encrypt? I believe the encryption of it would be limited to variables of js application and not files on the host

You're asking
What kind of data could be encrypted using javascript?
and Bergi answered that in the comments:
In general, you can encrypt all data that can be represented in binary
That's true, but this is not what you're actually trying to ask. I believe you're looking for scenarios where crypto libraries are useful in the browser. But more on that a little further down.
I believe the encryption of it would be limited to variables of js application and not files on the host
Yes and no. Anything that can be accessed by JavaScript, can be encrypted. Whether this encryption adds any security is a whole other issue. Values that are accessible through variables in JavaScript code can be encrypted. The same goes to user input which includes files that the user explicitly opened in order to upload in a file dialog (example).
Additionally, your JavaScript code has access to the whole file system in Chrome if you really want it.
Here are some scenarios where using Cryptography in JavaScript could make sense, but not all of them are recommended (not exhaustive, but common):
File storage (i.e. Mega) where the symmetric encryption key is never sent to the server but kept on the client or is directly entered by the user. Its security depends on your trust that the service provider doesn't change their own JavaScript and log the key that was used for encryption.
Password-manager (i.e. clipperz) is similar to file storage, but its code is injected to other sites and it must be resilient to not blurt out all its secrets. It can use many different cryptographic primitives.
Poor-man's HTTPS (i.e. too many Stack Overflow questions) where the server has its RSA private key and sends the RSA public key over HTTP (sic!) to the browser. The browser can encrypt any data and send it back to the server (maybe also establishing a symmetric key in the process). The server can decrypt the message with its private key and respond. This is sort-of secure as long as there is no man-in-the-middle attacker that simply injects its own JavaScript that copies any browser data to the attacker's server. SJCL implements ElGamal encryption instead of RSA for this use case.
Hashing data before uploading in order to check for transmission errors or achieve deduplication (no need to upload file, because somebody else already did so). Hashing is technically in the realm of cryptography and many libraries to that.
Online calculators (i.e. my authenticated encryption tests) where valid and easy to use implementations or algorithms can be used directly when implementing the same algorithms in another language. The data is never sent to the server and is encrypted purely in the browser. My "calculator" can be used to test ones own implementation, because it is verified by various test vectors. Others are there to help friends pass hidden messages without proper e-mail encryption.
These should not be done with browser-based crypto:
If you're using only symmetric encryption over HTTP and the exact same key is present at the server and the client, then you have a problem, because the key must be sent in some way for the client to the server or back. If you send the encryption key from the server to the client or the other way around you need to encrypt your symmetric encryption key. The easiest way to do this would be to use TLS. If you use TLS, then the data as well as key are encrypted, so you don't need to encrypt it yourself. This doesn't provide any security, just a little bit of obfuscation. Any passive attacker (observer) can read your messages. You should read: Javascript Cryptography Considered Harmful
Hashing a password for log in is a bad practice. The general consensus is that you need to hash a password many times (PBKDF2, bcrypt, scrypt, Argon2) in order to check whether a user has sent the correct username and password. Some think that if we hash on the client, the password is not sent in the clear over the network and everything is secure. The problem is that if they think that, they are not using HTTPS (which they need). At the same time, the hashed password is their new password. If the server doesn't implement a constant-time comparison, it is trivial to use a timing side-channel attack to log in as any person which you know the username of.
JWT for sessions: Part 1 and part 2

Cookies are in fact accessible via JavaScript, just like the DOM is.
You could encrypt them by running the value you want to store through the encryption algorithm.
Depending on what you want to store and how the encryption/decryption mechanism works this may or may not be a good idea.

Related

Encryption and Decryption in and out of codeigniter

I am creating an application based on codeigniter and will work as a API Centric application, i want to implement security , so that the user accessing the API from their own portal should get a public and private key from my portal and then every request they send to my server to get data should be encrypted by the public key and the server should decrypt the data using the private key getting the private key stored in the database
Now the problem is that how can i implement that, so that the user shouldn't go to hard proceedures to encrypt the data using the public key, and i should also be able to decrypt the information using private key within the codeigniter. and also if the encryption is made by javascript still it should be decrypted via codeigniter. I need some secure method to do that, so that i can avoid man in middle attacks and other threats
Thanks
The easy answer is, use TLS.
If you've implemented your server interface as a web API, then this is as simple as configuring your web server front-end to accept connections over HTTPS. Your web server (and the browser / HTTPS client library on the client side) will then take care of most of the complicated handshaking, authentication and encryption details for you.
TLS is far from a perfect security protocol, but if used properly, it generally does the job, and it does it with much less hassle or opportunities for mistakes than designing your own protocol would.
If you really want to "roll your own" secure communications scheme, you're first going to have to familiarize yourself with the theory of cryptography and the various available algorithms. In particular, to implement an effective hybrid cryptosystem, you're going to need:
an authenticated public-key based key agreement protocol (preferably something based on the Diffie–Hellman key exchange, and thus providing forward secrecy) to provide the client and server with a temporary shared key;
an authenticated symmetric encryption algorithm, to provide a secure channel between the client and the server using the shared key; and
if the data is transmitted as discrete messages within the secure channel, a communications protocol capable of detecting message replay attacks (e.g. through the use of sequential message numbers).
While all of these can be implemented using only a few discrete crypto primitives — a block cipher (e.g. AES), a public-key encryption/signature algorithm (e.g. RSA), and possibly a hash function (e.g. SHA-256) and some way to do modular exponentiation for Diffie–Hellman — it's generally easier to use protocols and schemes that you crypto library already implements a high-level interface for.
Unfortunately, the most widely implemented schemes also tend to be the older ones, which may be slower and have weaker security guarantees than more modern schemes. That said, if I had the choice (and keep in mind that I'm by no means a true crypto expert), here's what I'd pick:
If the client needs to authenticate itself using a password, I'd pick SRP for the key agreement protocol. If both sides have public signature keys known to the other, the problem is somewhat simpler, and could be handled simply by using raw Diffie–Hellman and then having both parties sign the D–H shared secret, or by using something like STS. (Note that, even with SRP, you may still want the server to authenticate itself to the client using something stronger than just knowledge of the client's password verifier.)
For the signature algorithm, any of RSA (with proper padding), DSA or ECDSA should do, as long as the key length is sufficient. (What counts as sufficient depends on the algorithm.) Where hash algorithms are required, I would, for now, use SHA-2; once the SHA-3 standard is finalized, it should also be a valid choice.
For the symmetric encryption part, I'd go with SIV (RFC 5297) for maximum fool-proofness, or with GCM if speed is critical or "on-line" encryption of large messages is required (and you don't have to implement it yourself). OCB could also be an option, if the patent exemptions are enough for your purposes, and EAX is perfectly good too, if not the absolute fastest. See also How to choose an Authenticated Encryption mode.
Generic composition of a block cipher (e.g. in CTR mode) and a MAC would also work, as long you make sure to apply the MAC to the message after encryption (end verify it before decryption). Any decent MAC should do, but HMAC is generally a safe and robust choice, if you have a good hash function available and don't need extreme speed. (If you do, a fast Carter–Wegman MAC like poly1305-AES may be worth considering.) Try to avoid the old CBC-MAC if you can; CMAC is much better.
In any case, I see no good reason to choose anything other than AES for the underlying block cipher at the moment, although it's always good to design your protocol so that new cipher options may be easily introduced (and old insecure ones deprecated) in the future.
To derive the symmetric encryption key(s) from the D–H / SRP shared secret, you'll generally need a key derivation function; HKDF (RFC 5869) is a good choice for this job, especially if you already use a hash function anyway. (It shouldn't be used — alone, at least — for hashing passwords, though; for that, you need a key-stretching KDF like PBKDF2 or scrypt.)
Also, as noted, I would design my communications protocol so that all messages carry a sequential message number and explicit sender/receiver designations, and so that messages with duplicate message numbers or invalid designations are discarded as forgeries. Conveniently, these message numbers + designators can also be used as nonces for the symmetric encryption protocol (possibly after hashing, if they would otherwise be too long).
These message numbers and designators don't necessarily have to be encrypted (although they do need to be authenticated as "associated data"); not encrypting them has the advantage that you can immediately reject any messages with bogus numbers or designators, even before attempting decryption.
Finally, always keep in mind that there may be exploitable gaps in what I've suggested above, or in the way you choose to apply my suggestions. Make sure to get as many competent security experts as possible to review your protocol and implementation before you use it for anything actually important.
As for specific crypto libraries or APIs in the various languages you mention, I'm not particularly familiar with those, and thus cannot offer detailed advice. Just look at the documentation of standard crypto libraries and see what they offer.
Create Signature for the both end client and server.
$key='any key';
$timestamp='current time stamp'
$url='url to access the file'
$signature = $sha1($key,$timestamp,$url);
use this function at both end and match the signature value and then let it access the data.

Established javascript solution for secure registration & authentication without SSL

Is there any solution for secure user registration and authentication without SSL?
With "secure" I mean safe from passive eavesdropping, not from man-in-the-middle (I'm aware that only SSL with signed certificate will reach this degree of security).
The registration (password setup, i.e. exchanging of pre-shared keys) must be also secured without SSL (this will be the hardest part I guess).
I prefer established and well tested solution. If possible, I don't want to reinvent the wheel and make up my own cryptographic protocols.
Thanks in advance.
For logging in you could try SRP from clipperz:
I'm not sure how strong the random number generator they use is. You might want to try and use the Crypto API to get stronger values. I'm not sure how you can get secure seed values in javascript without using Crypto API.
For sending initial password to server you could use public key encryption. So the server sends the client its public key (ok under the no mitm assumption) and the client encrypts the whole registration request when registering. Cipperz has support for public key encryption but in a very raw form. Often you use public key encryption to encrypt a randomly generated symmetric key and use the symmetric key to encrypt the payload. You have to be quite careful with padding/etc to make public encryption properly secure. I don't know of any robust public key crypto libraries for javascript.
You may want to check out jsbn for public key encryption because it looks like it does padding correctly. Though, I suspect it suffers from insecure random number generation. It would be a good idea to use Crypto API or make the user bang the keyboard to generate some entropy. Snippet from rng.js
// For best results, put code like
// <body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'>
// in your main HTML document.

openssl decryption in javascript in browser

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.

Encryption: simulate SSL in javascript and python

Because of china Great Firewall has blocked google appengine's https port. So I want to simulate a Secure Socket Layer by javascript and python to protect my users information will not be capture by those ISP and GFW.
My plan:
Shake hands:
Browser request server, server generate a encrypt key k1, and decrypt key k2, send k1 to browser.
Browser generate a encrypt key k3, and decrypt key k4, send k3 to server.
Browse:
During the session, browser encrypt data with k1 and send to server, server decrypt with k2. server encrypt data with k3 and response to browser, browser decrypt with k4.
Please figure out my mistake.
If it's right, my question is
how to generate a key pair in
javascript and python, are there
some libraries?
how to encrypt and decrypt data in
javascript and python , are there
some libraries?
You have a fundamental problem in that a JavaScript implementation of SSL would have no built-in root certificates to establish trust, which makes it impossible to prevent a man-in-the-middle attack. Any certificates you deliver from your site, including a root certificate, could be intercepted and replaced by a spy.
Note that this is a fundamental limitation, not a peculiarity of the way SSL works. All cryptographic security relies on establishing a shared secret. The root certificates deployed with mainstream browsers provide the entry points to a trust network established by certifying authorities (CAs) that enable you to establish the shared secret with a known third party. These certificates are not, AFAIK, directly accessible to JavaScript code. They are only used to establish secure (e.g., https) connections.
You can't stop the men in the middle from trapping your packets/messages, especially if they don't really care if you find out. What you can do is encrypt your messages so that trapping them does not enable them to read what you're sending and receiving. In theory that's fine, but in practice you can't do modern crypto by hand even with the keys: you need to transfer some software too, and that's where it gets much more awkward.
You want to have the client's side of the crypto software locally, or at least enough to be able to check whether a digital signature of the crypto software is correct. Digital signatures are very difficult to forge. Deliver signed code, check its signature, and if the signature validates against a public key that you trust (alas, you'll have to transfer that out of band) then you know that the code (plus any CA certificates – trust roots – sent along with it) can be trusted to work as desired. The packets can then go over plain HTTP; they'll either get to where they're meant to or be intercepted, but either way nobody but the intended recipient will be able to read them. The only advantage of SSL is that it builds virtually all of this stuff for you and makes it easy.
I have no idea how practical it is to do this all in Javascript. Obviously it can do it – it's a Turing-complete language, it has access to all the requisite syscalls – but it could be stupidly expensive. It might be easier to think in terms of using GPG…
(Hiding the fact from the government that you are communicating at all is a different problem entirely.)
The other answers here are correct: You won't be able to securely deliver the JavaScript that is going to be running on the client. However, if you just want to look into this stuff some more anyway, check out the opensource project Forge. It has an SSL/TLS implementation in JavaScript and a simple Python SSL server:
http://github.com/digitalbazaar/forge/blob/master/README
If you want to read up some more on its uses:
http://digitalbazaar.com/2010/07/20/javascript-tls-1/
http://digitalbazaar.com/2010/07/20/javascript-tls-2/
There's a big problem, if security really is a big concern: Your algorithm is going to be transfered unsecured. Can you trust the client at all? Can the client trust the server at all?

Client-side hashing/salting over HTTPS

I'm wondering what the serious issues are with the following setup:
Username/password login scheme
Javascript/ajax requests the salt value from the server (we have established in previous questions salt is not a secret value)
Javascript preforms an SHA1 (or otherwise) of the password and salt.
Javascript/ajax return the hash to the server
The server applies another salt/hash on-top of the the one sent via ajax.
Transactions are over HTTPS.
I'm concerned about problems that may exist but can't convince myself that this is that bad of a setup. Assume that all users need javascript enabled as jQuery is heavily used on the site. It's basically attempting to add an additional layer of security to the plain-text of a password.
As always: be very careful about designing cryptographic protocols yourself.
But that being said, I can see the advantage in the scheme. It will protect against the password being revealed through a man-in-the-middle-attack and it will ensure that the server never sees the actual password, thus preventing some inside attacks. On the other hand it does not protect against man-in-the-browser, fishing etc.
You might want to read through RFC 2617 about HTTP Digest access authentication. That scheme is similar to what you propose.
All that effort of passing salts and hashes between the client and server is already built into the underlying HTTPS/SSL protocol. I would be very surprised if a security layer in javascript is going to help very much. I recommend keeping it simple and use plaintext over SSL on the client-side. Worry about encryption on the server-side.
This doesn't add any additional security. The JavaScript code is present in the client, so the hashing algorithm is known. You gain nothing from doing a client-side hash in this case.
Also, there's no reason why the client should know about the hashing salt. It actually should be a secret value, especially if you're using a shared salt.
I'll 100% disagree with the accepted answer and say that under no circumstances should an original password ever Ever EVER leave the client. It should always be salted and hashed. Always, without exception.
Two reasons...
. The client should not be relying that all the server components and internal networks are TSL. It is quite common for the TSL endpoint to be a load balancing reverse proxy, which communicates with app servers using plaintext because devops can't be bothered to generate server certs for all their internal servers.
. Many users are pathologically inclined to use a common password for all of their services. The fact that a server has plaintext passwords, even if only in memory, makes it an attractive target for external attack.
You're not gaining anything. There's no point to a salt if Joe Public can see it by clicking View > Source, and the old maxim about never trusting client input goes double for password hashing.
If you really want to increase security, use a SHA-2 based hash (SHA-224/256/384/512), as SHA-1 has potential vulnerabilities. NIST no longer recommends SHA-1 for applications that are vulnerable to collision attacks (like password hashes).

Categories

Resources