URL Encryption for Ids - javascript

I want to ask some question regarding encryption and security point of view. Basically, I want to encrypt my URL to hide the Ids. Tell me which is the best method to do it ? I have read about md5, SHA256, RSA encryption.
I want to clear one thing that the method which you will told me should be application in both JavaScript and php.
And one more question, which encryption method are used by Facebook, instagram and twitter ? Please share me an authenticate link for confirmation of their encryption method method.

So, if I get it right, you want to send secret values to a server using GET requests - the values are to be added to the URL as parameters, and you wish to encrypt them to protect them.
I do not recommend this. It would (probably) involve giving the end user a web page that has your encryption algorithm on it. An attacker could replace that page when it is first sent to your end user, and modify it to contain their own code.
If you insist on doing this, you could use any cryptographic algorithm (note that MD5 and SHA256 that you mention aren't encryption algorithms but cryptographic hash functions). You could use RSA, but a symmetric algorithm like AES is faster, if you can find a way to exchange keys in a secure way.
What you should do, is hide your communications using TLS or a similar protocol. In this way you are using the built-in cryptography that practically every computer has.
The values that need to be communicated in secret can be sent via a POST request. This has the additional advantage that it will be easier to protect your system from replay attacks.

Basically, I want to encrypt my URL to hide the Ids. Tell me which is the best method to do it ?
What People Want To Do Here
What People Should Do Instead
Use random_bytes() and one of bin2hex() or base64_encode(). If you use Base64, make the number of bytes you generate an even multiple of 3 (e.g. random_bytes(24) for a 32-character string).
You can also use URL-safe base64 like so:
<?php
use ParagonIE\ConstantTime\Base64UrlSafe;
$token = Base64UrlSafe::encode(random_bytes(24));
But encryption is simply the wrong tool for the job.

This is encryption you have mentioned that is used for security reasons in PHP when you are saving password into DB. Then you can use such encryption.it converts original text into encrypted form.it is much harder to hack encrypted password.it's important technique for security reasons.

Related

Secure encryption key in javascript

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.

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.

Encrypting PIN without using JavaScript

This is our dilemma. We have an app that uses JavaScript to encrypt an entered PIN value. The risk here is the encryption is exposed to the public. Although it is secured because it uses asymmetric key encryption, it is still susceptible to a brute force attack. Something like attacker entering PIN values as trial and error, encrypting it then submitting the request. So as not to allow an attacker to get hold of the encryption logic, we need another way to hide this. Moving the encryption logic to the back end would allow the PIN to be exposed during submission (e.g. can be seen by browser request interceptors).
Is there any solution to this?
Never put your encryption on the client side, you need to do back-end encryption or your logic will get compromised.
Always use HTTPS when you are transfering sensitive information to protect it from 3rd-party.

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.

Categories

Resources