Encryption: simulate SSL in javascript and python - javascript

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?

Related

A safe way to send and show passwords to client

I'm building a password manager site using nodejs on the back end. When the user registers and saves a password I encrypt it and then store it in the db, so it's safe. The problem is that I need a safe way to send it from the database and show it to the user when needed. Which is the best way, send it encrypted to the client and decrypt it with a script or decrypt on the back end before sending it? Is https safe enough to protect requests and responses?
Try encrypt and decrypt at device level, so the only risk you take is getting the master password. A good way to do that is with: https://nodejs.org/api/fs.html.
With FS can you write and read data from device level
When making decisions about cryptography, ask two essential questions:
What is your threat model?
Should you be implementing it yourself or use an existing solution (such as BitWarden, an open-source password manager)?
Your seemingly-simple question is tricky, because Web security in general is a complex topic. In an application such as yours, several layers are involved, and you must decide what to do about each of them in your threat model:
Client/browser
Front-end server
Back-end server (can be the same as the front-end server depending on architecture)
Database
Depending on who controls what, the answers will be different. For example, if you're developing a password manager to be deployed on a company's premises, then it likely won't matter whether you encrypt/decrypt on the "back-end" or on the "front-end", as they'll usually end up being the same host, managed by the same IT people. A compromise of the host can result in injecting malicious code, which can then intercept all passwords, keys, etc. right there in the browser, and it's little help that all crypto is done on the client when the client-side code is controlled by the attacker.
In such cases, what will matter more is policy decisions - e.g. if the passwords sometimes safeguard GDPR-subjected personal records, you may need to implement the principle of least privilege and make the journey of the plaintext passwords as short as possible - whether a server-hosted "site" can ever accomplish this becomes an organizational/legal question, rather than a technical one.
Analyze your threat model carefully - what attack scenarios are you defending against? Do different people own the DB layer and the back-end servers, or could a single person dump all DB data and undetectably replace the client-side JS? What do your defenses protect - data at rest, data in transit? You might find that, depending on your desired security properties, a Web-based password manager is not feasible. On the other hand, it may be that you're after simple, single-tier deployments, in which case your job is easier as you can do crypto on the back-end.
The least you could do, if you decide to roll your own password manager, is to look at existing software and learn from it. Pick something that has been audited (e.g. Bitwarden!), find the audit document, see what pitfalls the original authors had run into.
HTTPS is extremely scrutinized that you can assume it's safe, so long you can keep openssl on your system updated. And honestly, your password manager's implementation or maybe your DB/OS patch level is more likely be vulnerable to attacks.
But to answer your question. In theory, decrypting on client side could be safer, but that is only if the decryption truly happens on client side, and that the decryption key is never transmitted over the wire.
That way, even if somebody else gains access to the data or taps data in transit (even with HTTPS decrypted), they will not be able to decrypt it because they will not get the decryption key.
Afterall, that is basically end-to-end encryption like some messaging app does, just in asynchronous fashion.
And why not ask how others do it if you are doing it. For example, 1Password actually built their own protocol called Secure Remote Password (SRP) and they published a white paper detailing the exact intricacies. So you can definitely take reference.

RSA or different information encryption method when work on Javascript side

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

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

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.

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.

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.

Categories

Resources