What is the easiest free method of encrypting my web traffic? I'd like to be able to log in to sites on my web server without sending my password in plaintext.
Edit: My web server is running on the LAMP stack , although it is a shared host so I don't have root.
Get an X.509 certificate (for example, generating your own, or getting one free from StartSSL), and use it to set up SSL—a server-specific configuration task.
If you can't configure a new listener in your web server, there's not really a good option. In theory you could do a little hacking with some JavaScript crypto library, like JavaScrypt, and come up with something safe. I've toyed with several options but I don't know enough about it to come up with anything I feel confident about.
I don't know your circumstances, but if it were me, I'd consider another host.
https
Use a self-signed certificate.
Tell us your web server software for a detailed implementation description!
Since you don't have root your best bet is to contact your hosting provider and see what they can do for you. You may already have SSL access (try using https://yourdomain.com) using a self-certified key.
You should be able to talk them into installing a StartSSL key for you. This provides you with SSL encryption and browsers won't complain that it isn't signed by a valid Certificate Authority.
As stated above, publishing your own certification is free, however knowing more about your environment, may get you more specific answers. Are you running IIS? What will you be logging into that needs encryption? Are you using Windows Servers on the back end?
use Digest Authentication. Since you're on LAMP, you can configure it on Apache with mod_auth_digest.
Since you are trying to reduce costs, any ssl solutions will probably not be an option.
First it requires a signed certificate that cost a bit, the free ones is not always included in all web browsers.
Second to be able to utilize an ssl certificate your server ip must be dedicated to you. This is not the case in every cheap web hosting option. There are technologies that in the future will make it possible to host multiple ssl enabled sites on a single ip, but it's not here yet.
As mentioned before Digest Authentication is one option that doesn't require ssl certificate or dedicated ip.
It's a method of authentication that doesn't reveal your password even though everything else in the communication is unprotected.
In Apache this can be applied in individual directories by specific .htaccess files.
I'll repeat the previous link on mod_auth_digest.
This one is usually already installed on most servers so you won't have to ask you web hosting provider.
You don't always require root access to setup Apache to use SSL, but you will likely need to modify config files, which is either done thru your providers interface, or via files via a shell account. Either way you will need a server certificate; either self-signed, from a major company like Verisign, or one of the smaller free places like cacert.org. As noted by others, this does require a dedicated IP to your server or instance on the server.
I would recommend SSL first, but mod_auth_digest isn't a bad backup idea.
Related
I've followed the guides / processes I can find about adding / binding an SSL certificate to a custom domain for my Azure Function, but cannot get a secure connection to work. How can I go about finding (and fixing) the problem?
The app is in place, and the custom domain is added. I've generated and uploaded the private key. I can access the function (and it runs) when called via the custom domain, but the browser will insist on showing "this is not a private connection".
I'm running on a pay-as-you-go / consumption plan, but I've understood this to be fine?
Is there something that I need to be doing within the Function code itself to allow it to make use of the code?
Is there any other way that I can see / debug why this binding isn't letting me create the right type of secure connection? I'm not sure how to go about diagnosing this properly.
I’d start with browser tools to view the certificate it is loading. Modern browsers are pretty good about flagging what aspects of certs are off (mismatch of domain, expiration, etc.). Also make sure you do this calling the https endpoint as May be defaulting to http
I learned a lot while trying to fix this, so herewith, my road to solution.
tl;dr - problem was with the certificate and its loading into Azure...I think. There was an issue with the DNS, but after that, reloading and rebinding the certificate in the Azure Portal over and over again seemed to to the trick.
Diagnosing
#jeffhollan mentioned this in his response below, but the browser did give a hint as to why it was reporting a non-private connection. It did show some correct details about the certificate, it showed some other host name instead.
Suspicious about the SSL certificate itself (I'd gotten mine from namecheap), I used these online tools to investigate the certificate, both quite helpful to me. There are lots of others like them, I'm sure:
https://www.ssllabs.com/ssltest/analyze.html
https://decoder.link/sslchecker
These pointed to two strange things - the hostname wasn't right (it was pointing to some strange shortener service) and the certificate was not signed by a trusted certificate authority.
The DNS Issue
When I obtained the domain (from GoDaddy), I set up the CNAME record to point to the Azure Function URL. That worked.
BUT, I didn't remove / update the A record, which was still pointing to that weird shortener service URL (was there when I got the domain).
Since I am currently only interested in having this single Azure Function accessible, deleting the A record was sufficient for me. This is probably not the best solution, but if I knew what it was, I wouldn't have had this problem in the first place...
I reran the tools above, and at least the host name was pointing to something Azure related, but still not working properly.
The Self-Signed Certificate Issue
I spent a lot of time with Namecheap's online support - really great service and very helpful. The suggestions did boil down to re-issuing the certificate and going through the various steps to upload and bind the certificate in the Azure Portal.
I only re-issued the certificate once. But I re-uploaded and re-bound it in the Azure portal 6-10 times. On the final time, it just seemed to work.
I don't know what the problem was. The support team and the online tools all pointed to the server (Azure) not having accepted / loaded the certificate correctly. I'm almost certain that I wasn't doing anything different during my upload attempts, so perhaps persistence was just the key.
I struggle to understand how it could have been a propagation / timing thing. I was fiddling with this over the course of 3 days. The DNS was sorted on day 1, and there was a lot of time between certificate re-uploads. From what I understand, propagation DNS should take about 30 minutes, rarely more than 60, but certificates and SSL don't generally form part of that? I don't know.
Learnings
As #jeffhollan mentioned, the browser gives some good hints. I'm embarrassed that this didn't occur to me sooner, but yeah...
The online SSL tools are useful for not only diagnosing SSL issues, but also testing their strength. Good finds.
Getting a handle on whether the issue is with (a) the certificate, (b) the server or (c) the DNS is a worthwhile first step. Having each managed by different parties probably makes it a little harder...
Here's the scenario:
Website A is served from a public domain example.com via HTTPS.
Website A needs to access a service B via WebSocket. Thus, the websocket also needs to be secure aka wss://.
The service B is currently not secured. I'm trying to secure it and I need to generate a certificate for it.
The service B is only available from the intranet. The WSS URL starts with wss://192.168.x.x (connecting by IP and behind a NAT). Yes, this also means that A can be fully used only from the intranet, although limited functionality is available through the internet. The typical case however is intranet use.
The computers which connect to website A aren't in a windows domain and do not currently trust any certificate authority that can be controlled by us. In other words, we cannot create a certificate that all these computers will trust by default. For that we would need to work with one of the large common authorities that everyone trusts, but I doubt they would issue a certificate for a NAT IP address.
The problem:
Since I cannot create a certificate that all the computers trust by default, I might as well create a self-signed certificate and use that to secure the websocket. However... I'm not really sure what will happen. I think that either the user will be prompted each time they connect, or the connection will fail silently anyway.
I can manually install the certificate on each machine, but that requires visiting them each separately, and if a new person wants to access the website, I need to remember to do it on their machine too. Not nice.
Is there some good solution to this? Can you make a website prompt for permanently trusting the certificate or something?
Most browsers have a built in function for permanently trusting unknown certificates, and, to be frank, I wouldn't trust any website, that tried to circumvent those mechanisms, even if they were intranet sites. If something like that appeared while visiting an intranet site, I would be more inclined to call IT Support and ask, if the website has been tampered with.
I would distribute instructions on how to add the certificate (maybe noting that mindlessly doing this on other websites than yours might be problematic) and deal with the cases that are unable to follow these instructions.
An alternative (although I don't have any personal experience with that) might be getting a free certificate from https://letsencrypt.org/ which, as far as I know, will be accepted in most browsers.
Firefox:
Chrome:
https://www.accuweaver.com/2014/09/19/make-chrome-accept-a-self-signed-certificate-on-osx/
At the moment I'm running towards the same problem only solution I can think about and what I'm trying is that I ask the user to click a button (which creates a pop-up window) with the webserver with the certificate which needs to be accepted. Then they accept the certificate and I ask them to reload (or restart the code by clicking the same button) then it should be able to work. But you will need a page on the w
I must see the traffic from an android phone to a secure server using wireshark on Windows.
All packets are encrypted with ssl but i don't have the key, how can i find it?
Thanks
The key will be on the server. It depends on what software the server is running as to where the key will be stored or in what format. If it's an Apache server, then look in the ssl.conf file for SSLCertificateKeyFile. (Depending on the configuration, this may actually be stored in a different configuration file, you can grep for the string.)
Once you have the file, you can add it to Wireshark under the "SSL" protocol preferences. For more, see the SSL page on the wireshark wiki.
If you only have access to the client, it's possible to decrypt traffic using the pre-master secret, but it's a lot more inconvenient and you generally need to rework your client software to output it (and then it's only useful for that specific session; and if you have that, you might as well just have the client log its traffic in most cases). If this is your case, and you have a mechanism to get the software to output its pre-master secret (or can modify the software to do so), I can update the answer with more on that scenario. But if at all possible, avoid it and use the server's private key.
If you have lack privileged access to the client or the server, this is by-design not a solvable problem.
I'm looking for some info about securing a website. The website is actually a kind of management console that can be accesses through a web browser. The console is currently only available on the internal network, but I want to make it accessible through the internet, only for some specific users/devices.
The first problem I faced is that the management console didn't provide authentication at all. To overcome that problem, I've installed apache, which I use as a (reverse?)proxy and in which I enabled basic authentication, so now I have to enter a username and password before I can access the console.
The thing that I want to do next is to prevent the username and password to be send over the line as plain text (I assume that's whats happening now). I think I have to make it a https connection for that, but I find so much information about that so that I'm a bit lost on how to continue. Can I make this work with self signed certificates or do I need to buy certificates somewhere?
You are right about securing passwords through https. I would suggest redirecting everything on your server through https, following this article.
I would suggest testing the whole solution without buying anything. Buying a certificate means that it would be bound to your server. I suppose that when you develop your solution, you use a development server. If you buy a certificate for your development server, then you would have to buy another one for your production server. Therefore, I would use a self-signed certificate for development and when the application is ready to go public, then I would buy a certificate recognized by all browsers.
In order to create a self-signed certificate you could follow this tutorial supposing you work on linux, or this tutorial supposing you work on windows.
Hope I helped!
Here is my requirements:
Usable by any mobile application I'm developing
I'm developing the mobile application, therefore I can implement any securing strategies.
Cacheable using classical HTTP Cache strategy
I'm using Varnish with a very basic configuration and it works well
Not publicly available
I don't want people be able to consume my API
Solutions I think of:
Use HTTPS, but it doesn't cover the last requirements because proxying request from the application will show the API KEY used.
Is there any possibility to do this? Using something like a private/public key for example?
Which fits well with HTTP, Apache, and Varnish.
There is no way to ensure that the other end of a network link is your application. This is not a solvable problem. You can obfuscate things with certificates, keys, secrets, whatever. But all of these can be reverse-engineered by the end user because they have access to the application. It's ok to use a little obfuscation like certificates or the like, but it cannot be made secure. Your server must assume that anyone connecting to it is hostile, and behave accordingly.
It is possible to authenticate users, since they can have accounts. So you can certainly ensure that only valid users may use your service. But you cannot ensure that they only use your application. If your current architecture requires that, you must redesign. It is not solvable, and most certainly not solvable on common mobile platforms.
If you can integrate a piece of secure hardware, such as a smartcard, then it is possible to improve security in that you can be more certain that the human at the other end is actually a customer, but even that does not guarantee that your application is the one connecting to the server, only that the smartcard is available to the application that is connecting.
For more on this subject, see Secure https encryption for iPhone app to webpage.
Even though it's true there's basically no way to guarantee your API is only consumed by your clients unless you use a Hardware secure element to store the secret (which would imply you making your own phone from scratch, any external device could be used by any non official client App as well) there are some fairly effective things you can do to obscure the API. To begin with, use HTTPS, that's a given. But the key here, is to do certificate pinning in your app. Certificate pining is a technique in which you store the valid public key certificate for the HTTPS server you are trying to connect. Then on every connection, you validate that it's an HTTPS connection (don't accept downgrade attacks), and more importantly, validate that it's exactly the same certificate. This way you prevent a network device in your path to perform a man in the middle attack, thus ensuring no one is listening in in your conversation with the server. By doing this, and being a bit clever about the way you store the API's parameters general design in your application (see code obfuscation, particularly how to obfuscate string constants), you can be fairly sure you are the only one talking to your server. Of course, security is only a function of how badly does someone want to break in your stuff. Doing this doesn't prevent a experienced reverse-engineer with time to spare to try (and possibly succeed) to decompile your source code and find what it is looking for. But doing all of this will force it to look at the binary, which is a couple of orders of magnitude more difficult to do than just performing a man in the middle attack. This is famously related to the latest snap chat flurrry of leaked images. Third party clients for snapchat exist, and they were created by reverse engineering the API, by means of a sniffer looking at the traffic during a man in the middle attack. If the snapchat app developers would have been smarter, they would've pinned their certificate into their app, absolutely guaranteeing it's snapchat's server who they're talking to, and the hackers would need to inspect the binary, a much more laborious task that perhaps given the effort involved, would not have been performed.
We use HTTPS and assign authorized users a key which is sent in and validated with each request.
We also use HMAC hashing.
Good read on this HMAC:
http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/