Mobile App with Cert Pinning - SSL Cert on DMZ box with trusted CA vs my own CA - security

I am developing a mobile app with certificate pinning. I will have a box in the DMZ that will proxy my requests. Should this server have a cert from a trusted CA or can I use the one I generated from my own CA?
What would be the benefits of using a trusted CA from a mobile client?
Also, I will hit several different servers afterward that will be using my own CA generated cert. Should I pin those as well? I am assuming yes, that pinning both will be best even within the network. But is the necessary?
Thanks!

If you use your own CA you gave to manage the revocation process yourself, which is hard.

If you use a custom CA, it means you will have to either:
Provision all the mobile devices that will use your App with your custom CA. If you don't control the mobile devices, this will be impossible to do and pushing a CA to a device's trust store is a liability anyway.
Disable the system's default certificate validation so that the custom CA is accepted by your App, and then re-validate the server's chain and do pinning. It is close to impossible to get this right so you will most likely end up with an insecure HTTPS connection.
Do buy a certificate from a trusted CA.
For the connections between the proxy and the internal servers, you could implement SSL pinning but it is less of a priority as the attack surface is reduced, compared to the mobile clients.

Related

Understanding SSL Certificate Types

I'm building my first web app and I have two questions about security.
I'll send and receive very sensitive data with POST request to my
api which will be hosted on Azure or AWS. Can I send and receive
data in plaintext over SSL, is it secure? I can access my
azure web site over https, is it secure enough or should I buy another
SSL sertificate?
I've searched a little bit and there are different types of SSL
certificates, I read some certificates provide green padlock or green address bar but I don't need these kinds of things since my web app only
will be available to my mobile app and there will be no content to browse. Only one page with download links to my mobile app in case someone finds this site. So all certificates are secure on same level for my situation?
P.S. I won't add custom domain name, if that's relevant.
Answering your questions one at a time;
Modern implementations of SSL are generally considered to be pretty
rock-solid; its used by banks, healthcare institutions, and major
internet companies. Sending data in plaintext, over SSL, is
safe enough for those applications, and trying to replace SSL with
your own encryption scheme is almost certainly more trouble than its worth.
You should probably get your own SSL certificate; I don't know what restrictions Azure has on https access, if any, and its always bad practice to rely on a key you cannot control.
SSL relies on networks of trust; browsers (and other internet applications) validate the certificates sites send them against a
set of trusted authorities. If the certificate has been approved
(signed with the authority's private key), the browser accepts the
certificate as genuine and uses it to negotiate an SSL connection
with the site without further complaint. This is what that green
padlock/address bar means; that a site has provided a valid
certificate signed by an authority the browser trusts. This doesn't
mean that a signed certificate is inherently more secure than an
unsigned certificate, however. Both use the same cryptographic
algorithms, and (can) have the same length keys, and the SSL
connections each can set up are equally secure. The difference
between the two is that you can't verify the "authenticity" of an
unsigned/self-signed certificate; an attacker could intercept the
connection and replace an unsigned certificate with their own
certificate, and the browser would have no way of telling if it got
the right certificate or not. You can overcome this problem in your
application, however, with a technique called "certificate
pinning".
Essentially, you package the public key for your certificate with
your application, and your application only accepts the certificate
associated with that key when setting up a connection.
Ultimately, it depends on your attacker model. Are you protecting this data from criminals and casual wiretappers? Or are you trying to hide it from government surveillance and intelligence agencies? For the former, an SSL certificate signed and issued by a reputable authority is more than sufficient. For the latter, you have to consider where your certificate is coming from, and who can access the root CA that issued it; it might be better to generate your own, and devise some further scheme on top of SSL.

IIS: self-signed certificate for external web api

My company has external web api service and I want to make it secure using SSL certificate. This service is called by internal application only. Is it secure to use self-signed certiifcate in IIS on production?
Yes it is secure to use a self-signed certificate even.though it is not best practice for Production environment.
Indeed the Root CA will be unknown and the client cannot validate the issuer. Your client will have to accept such a certificate (this means you will have to handle the certification check yourself)
How to ignore the certificate check when ssl
If the API is used only internally, it is not a big deal. If you have some external consumers, you should really just go and buy a certificate.

Is there a way to form secure connections without trusted third parties?

I've just recently learned a bit about how encrypted messages are sent across the Internet, and it seems that it relies a lot on "trusted third parties" My problem is that I don't trust anyone, is there some way to form an encrypted connection between two computers without prior secrets or the need to trust anyone?
Yes, by creating a "Certificate Authority" (CA) and installing its certificates on the machines.
The third parties you're talking about issue certificates, and sign those certificates using a CA certificate that is included in popular operating systems and/or web browsers. You can create your own CA certificate and install it onto the machines in question alongside those third party certificates. Then you can issue your own SSL certificates which will be recognised by those machines without any third party involvement.
Note that the CA certificates aren't "prior secrets" - there's nothing secret about the certificate itself. It has a private key, which you use to sign your SSL certificates, but that key doesn't need to be on the machines in question (and shouldn't be).
There are plenty of sites that will walk you through the process - a quick Google turned up this one for example: Creating Your Own SSL Certificate Authority.

J2ME intermediate certificates

In J2ME when you sign a JAR with a certificate chain that includes an intermediate certificate (such as one from obtained from Verisign), does the device need to have the intermediate certificate installed as well as the root certificate during verification?
I am guessing the answer is no because the intermediate certificates are stored in the JAD file in the MIDlet-n-m properties where m is 2 or greater, and I believe the device references these while verifying. If that is true then J2ME certificates are different from SSL website certificates which require the intermediate certificates be installed in the browser, correct?
Finally if this is all true then couldn't anyone who gets a certificate from Verisign or any other CA with their root certificate on the device just go ahead and sign their friend's certificates and then their friends will be trusted?
Seems like a flaw in the system if this is all true...
The certificate one gets from verisign would typically be trusted to sign a MIDlet but not another certificate. Certificates trusted to sign MIDlets usually are not trusted to sign native applications either.
Between this and the (admitedly advanced and not always available) ability to revoke certificates, the system is fairly safe as long as trust is preceded by due diligence (so your Mobile Network Operator doesn't start trusting trojans and such...)
Frankly, it's not like mobile airwaves are inherently secure anyway.

How does SSL actually work?

Whenever I see it being talked about, it sounds like one simply 'turns on' SSL and then all requests/responses to/from an online server are magically secure.
Is that right? Is SSL just about code - can I write two apps and make them communicate via SSL, or do you have to somehow register/certificate them externally?
Secure web pages are requested on port 443 instead of the normal port 80. The SSL protocol (plenty complicated in and of itself) is responsible for securing communication, and using the certificate information on both the SERVER and the BROWSER to authenticate the server as being who they say they are.
Generating an SSL certificate is easy. Generating one that is based on the information embedded in 99% of web browsers costs money. But the technical aspects are not different.
You see, there are organizations (Verisign, Globalsign, etc...) that have had their certificate authority information INCLUDED with browsers for many years. That way, when you visit a site that has a certificate that they produced (signed), your browser says:
"well, if Verisign trusts XYZ.com, and I trust Verisign, then I trust XYZ.com"
The process is easy:
Go to a competent SSL vendor, such as GlobalSign. Create a KEY and Certificate Request on the webserver. Use them (and your credit card) to buy a certificate. Install it on the server. Point the web-browser to HTTPS (port 443). The rest is done for you.
SSL is a protocol for encrypted communications over a TCP connection (or some other reliable scheme). The encryption uses public key encryption using X.509 certificates. SSL handles both privacy and trust. These are related: if you don't trust the server, you don't believe that the server hasn't handed out its private key to everyone in North America.
Thus, the client has to trust the server's certificate. For public sites, this is arranged via a hierarchy of certificate authorities, with the root authorities trusted, automatically, by browsers and things like the JRE's socket implementation.
Anyone can generate a self-signed certificate for a server, but then the client has to be manually configured to trust it.
SSL is not, in itself, a magic bullet that makes everything secure. Security has no such things.
SSL is, however, an already-designed, ready-to-use system for solving a common problem: secure stream communication over a network connection.
There are two things you need to do to secure your application with SSL:
Modify the application's code to use SSL.
Determine the certificate trust model (and deploy and configure the application respectively).
Other answers and documentation provide better answers to how to do each of these things than I could provide.
I'll throw caution to the wind and attempt to condense an enormous subject.
SSL attempts to solve two problems:
1) Authentication and hence trust i.e can the client trust the server and vice versa
2) Communication without eavesdropping
1) Is handled by means of an intermediary i.e a trusted 3rd party - these are called 'Root Certificate Authorities' ( or Root CAs ) examples include Verisign, RSA etc
If a company wants to authenticate users and more importantly if a user wants to authenticate the company's website it's connecting to i.e your bank then the Root CA issues the company a certificate which effectively says 'I the trusted Root CA verify that I trust that Company X are who they say they are and am issuing a certificate accordingly'. So you get a chain of trust i.e I trust the certificate from ACME Co because Root CA Verisign created and issued it.
2) Once the two parties have authenticated then the certificate ( typically X590 ) is used to form a secure connection using public/private key encryption.
Hopelessly simple and incomplete but hope that gives a rough idea
Yes and no. You should self-sign a certificate and test the site with SSL internally before deploying it with SSL, first of all. To make the public site secure under SSL, you will need to purchase a certificate from one of any number of certificate providers. Then you will have a certificate signed by a trusted third party, tied to your domain name, so that users' browsers won't complain that the certificate is invalid, etc. Turning SSL on is pretty much just flipping a switch, otherwise.
For the most part you need to buy and register a certificate externally.
You need to have your server certificate signed by a Certificate Authority (CA), for which they will charge you. The client needs to trust that CA and have a copy of the relevant CA public key. The client can then check that you are who you claim to be (including domain name (from DNS) and display name for https).
This is a good tutorial on how to create self signed certificates for Apache.
If you want to know how SSL works on either the Server or the Client, then I suggest Googling it. As you suspected, it is a ridiculesly complex procedure, with lots of communication between the client and server, a lot of very peculiar math, and tons of processing. There is also a lot of theory involved, several protocols and many different algorithms and encryption standards. It's quite incredible how changing http:// to https:// is so simple to the user, but results in so much work for both sides, and is so secure. To really understand it you need to take a security course (multiple courses to fully understand it), as the entire history of encryption goes into making your login to Gmail secure.
Turning on TLS (colloquially "SSL") does not make your site magically secure. You may still be vulnerable to application-level vulnerabilities like stack overflows, SQL injection, XSS, and CSRF.
As other answers have explained, TLS only protects against a man in the middle. Traffic between a client and a properly-configured TLS server cannot be intercepted or modified, and the client can reliably confirm the identity of the server by validating the X.509 certificate. This prevents an attacker from impersonating your TLS server.
SSL actually does two things:
Encrypts the communication so that an observer seeing the data stream will not be able to read the conversation.
Guarantees that you are talking to who you think you are talking to.
It is only for #2 that you need to get official certificates. If you only care to encrypt the communication without setting up a trust relationship, you can use self-signed certificates or you can use an algorithm that does not require certificates (i.e. Diffie-Hellman).

Resources