We are developing the automation software for Windows which communicates with the certain devices via our own private connection protocol. That software package consists of several server (including HTTP) and client applications and usually runs in a private corporate environment. What most important here is the fact that usually our server components won't have the domain names (just having IP address is enough). Now we have a request to create web applications which will then communicate with our server components securely from the internet. The most obvious way to do so is HTTPS/SSL. We can do this. They question is: do the consumers of our package will need to buy SSL-certificates from a trusted CA (having a self-signed certificate is not enough)? Can the trusted CA issue a certificate just on the basis of IP address but without domain name?
I think there are two options here:
- Server-side certificate - in this case you need to get one certificate on your server. Hostname instead of IP address is a must and is very much preferable over the Internet and will save your customers a lot of hassle in the future. There is an 'altSubject...' field in the certificate where an IP address can be entered and it will still validate. Now, the client just need any SSL client and your cert issued by a CA trusted by the SSL client will work.
- Client-side certificate - you can be the CA and issue your own certificates to all of your clients and as long as your Web server establishes the validity of the incoming client cert, it proves identity as well as confidentiality of transport. Of course, these can be CA-issued as well. This approach would be slightly preferable in your scenario as you would be able to revoke certs that don't pay for your software and still want to use it :)
Your problem is on the client side. In a SSL connection, the client must use the server's public key, and therefore must make sure that it knows the correct key; the goal of an attacker would be to induce the client into using a fake public key. SSL defines that the server sends his public key as part of a chain of certificates, which the client then validates (the complex process of verifying signatures, dates, revocation status and a lot of extensions). But a valid certificate does not teach much to the client as itself; the client must make sure that it knows the server's certificate. Therefore, the client must look for the "expected server identity" in the (valid) certificate.
So you have two important facets to the subject:
The server's certificate must be valid against a given set of trust anchors (aka "root certificates") that the client trusts a priori.
The server's certificate must contain its identity in a way which will convince the client.
In the usual Web context, the client is a Web browser, and the browser vendor (or OS vendor) has already provided it with a huge set of "default root CA". The identity matching is described in RFC 2818: since the client tries to connect to an URL which includes a host name, the client will look for the same host name in a couple of places in the certificate (the CN part of the subject name, and in the Subject Alt Name extension). This is where "domain names" have an impact: the name which the client looks for in the certificate is also the name which the client uses against the DNS to know where to actually connect.
If you control both client and server code then you can choose whatever mechanism you wish. The client could "know" the server's public key a priori (hardcoded in the code, or through a local configuration file), and totally ignore the server's certificate. The client can validate the certificate with regards to any set of CA that you see fit, not necessarily the same CA than the ones which are included in Web browsers. You could maintain your own: if that's just for your servers, that CA will issue a couple certificates per year at most, so it can use rather crude technology (you will want to keep it in a safe, but it can use cheap software and manual procedures; see for instance EJBCA or even OpenSSL). And, last but not least, you need not look for the server's identity in the same places than what RFC 2818 mandates. Thus, there is no hard requirement for messing with domain names.
If you do not control the client code (e.g. the client is a Web browser, or some existing library code which insists on using the same rules than Web browsers, i.e. RFC 2818), then you need, by definition, to comply with the Web usages: link with domain names, certificates from a "recognized" CA (one which is trusted by the client system).
An SSL certificate provides authenticity of a common name, which in the world of HTTPS is the domain name. Essentially, the browser verifies a certificate based on validation of the certificate and comparison of the common name to the current domain. So, for
www.example.com, the certificate must have a common name that matches
www.example.com. This might not be direct match, since subdomain wildcard certificates are available that will match
*.example.com. However, a certificate generated for
foobar.com will never be allowed to match
barfoo.com, or vice versa. Keep in mind that the implementation if this is strictly within the browser.
However, in a custom client implementation, you can enforce the common name in any way you see fit. It might be a person's real name, a GUID, an IP address, etc. In fact, the data stored within the common name field is not important, but the enforcement of that data against a real identity is. The reason a domain name is used is because a domain may represent a variety of IP addresses. The DNS records for a particular host might have an
A record (IPv4 address), an
AAAA record (IPv6 address), an
MX record (mail server), etc. In fact, it may have more than one
A record, in order to load-balance across multiple physical hosts. Furthermore, IP addresses can be dynamic and are frequently reallocated. This means that a single site cannot always be identified by its IP address. Generating and maintaining SSL certificates for all IP addresses associated with your domain would be cumbersome, and would require you to re-issue new certificates if the IP address changes. This is far from ideal, so having a single SSL certificate authenticate the domain is a better solution.
What I don't understand is why you would not have your servers associated with a domain name. Manually issuing SSL certificates to IP addresses will be painful, and it'll be much more difficult to get a notable CA to sign them for you. I'll also require you to push product updates if your server IPs ever change, instead of just altering the DNS record yourself. If your clients need to get to your server from a new device, they'll have to write down your IP and send it over, rather than just memorising an easy domain name. Besides, you can pick up domains for next to nothing - as little as $10/yr in some cases.