Self-Signed Certificates: A Broader Perspective

Some time ago, I published an article advocating against self-signed certificates. It engendered some great responses, although a few seemed confused by a couple of core concepts related to certificates. So I thought it might be a good time to revisit the subject and clarify.

Certificates are Digital ID Cards

Although one prominent individual disagreed with me on this, I’m holding fast to this. Certificates are about online identification,  nothing more, nothing less. When used to create a digital signature, as on an email, a certificate is what tells you what human being signed the email When used to sign software, a certificate tells you which company published the software (software signing certificates are typically issued only to organizations, not to individuals). When used to encrypt data, as in a website SSL connection, the certificate tells you who you are sending data to. After all, the point of encryption is to keep a conversation private; you can’t possibly have privacy if you don’t know who you’re communicating with in the first place.

Different levels of certificate often have different identity verification measures in place. For example, an email certificate typically requires that you do nothing more than prove you have control over the email address in question – so an issuer will usually just email you the certificate. An Extended Verification (EV) SSL certificate, on the other hand, requires issuers to perform an extensive check of public records and other sources to verify that the person requesting the certificate is indeed the organization in question. EV SSL certificates were added after a bunch of commerical Certificate Authorities jumped into the game and started issuing “normal” SSL certificates with little in ther way of actual identity validation – meaning you could be on an HTTPS website, get the “lock” icon in the browser’s address bar, and still not be guaranteed that your “conversation” was between only you and the organization you expected.

So the point of a certificate is to identify the party presenting the certificate. You can argue that, for some given kind of certificate, a CA might do a poor job of validating the identity of ther certificate holder. Fine. That negates the value of that CAs certificates, but it doesn’t negate the fact that identity is the point of certificates. That CA, and its users, simply don’t “get it.”

And incidentally, if you’re of the belief that certificates have nothing to do with identity, I’d dearly love you to drop a comment (and not a 140-character Twitter blurb) to help me understand your perspective. Thanks in advance!

Self-Signed Certificates

A couple of folks seemd to think that a self-signed certificate was one which their organization issued (e.g., “we signed it”) versus one purchased from a commercial CA (e.g., “they signed it”). Not so. A self-signed certificate is one in which the holder of the certificate is also the issuer. It’s like you walking into a bar, being asked for ID, and handing the bouncer a slip of paper that has your name printed on it, and which you clearly wrote in crayon. “Don Jones asserts that this is indeed Don Jones,” is what a self-signed certificate says.

Many people will have their computers create a self-signed certificate – the computer is asserting that it is the computer in question – for development purposes. PowerShell Web Access, as one example, can create a self-signed certificate (“computer SERVER862 guarantees that it is SERVER862”) as a “test” mode, allowing you to deploy PWA quickly and without needing a “real” SSL certificate. I came down pretty hard on using self-signed certificates for these purposes in my original article. I still kinda stand by that, although I was really only thinking about my usual audience – PowerShell people.

I do get why regular software developers like self-signed certificates (cheap ‘n’ E-Z) during development, and most of them have a part of their build chain where a “real” certificate gets used. Oversimplified example: developer self-signs code during development so it’ll run, organization’s “real” code-signing certificate is used once the code is compiled, checked in, passes its automated tests, and is ready to deploy during production. This is fine – the developer is essentially asserting their own identity. but only to themselevs. “I guarantee to myself that I am myself” is what’s happening in that case, and as slightly schizo as it may sound, it’s totes fine.

It’s a smidge different in the PowerShell world, where self-signed certificates get backed into things like DSC configs and then deployed to production. Self-signed certs really have no value in production, unless you’re saying, “having to use a certificate for ___ is stupid, so I’m just going to use a made-up one, tick the checkbox that says I have to use certificates, and laugh all the way to the malware attack that I’ll eventuyally be subjected to because I simply don’t understand security fundamentals.”

There’s one place where a self-signed certificate is not only acceptable in production, but demanded, and that’s when you set up your own root CA. The root self-signs its own certificate. This is the only way to do things. In order for the CA’s other certificates to be accepted by anyone, they must first accept the root as a “trusted authority.” This is essentially the same as the Department of Motor Vehicles saying, “hey, we’re going to be issuing ID cards, and we’re the DMV, and we say we’re the DMV, and you need to be okay with that.” Society accepts that, and it’s the same as trusting a root CA’s self-signed certificate.

CAs do not issue self-signed certificates; CAs are literally the opposite of self-signed certificates. A CA, commercial or private, issues what we’d call a “normal” certificate.

But PKI is Hard!

Damn straight it is. It’s hard in part because of the immense trust and security we place in PKI. It’s hard in another part because the people who make PKI software aren’t terribly inventive, and because the industry as a whole hasn’t done much to make certificates more manageable at scale.

Certificate rotation – replacing about-to-expire certificates with new ones – is a huge PITA for one certificate; if you have 800 web servers it’s practically a full-time job unless you have weapons-grade automation in place. Automation that, on Windows in particular, is unacceptably hard to create. Windows’ concepts for certificate management are Byzantine. None of this changes the fact that self-signed certificates are a Bad Idea in production. I mean, driving in LA traffic is hard, too, but you don’t see people walking along the 405 instead.

What we don’t have are some of the things you’d expect us to have. For example, why don’t operate systems, web servers, and the like have some protocol they can use to “check in” with an enterprise CA to automatically obtain and renew certificates? Surely there’s some means for a node on a known network to identify itself (not IP address, because an intruder would have one also). Active Directory’s certificate auto-enrollment is close, because node have a password in AD and can positively identify themselves, but too many server workloads aren’t happening on domain-joined machines for this to be a total solution. A really insufficient amount of thought has been put into this by OS and server vendors.

Hiring a Notary

Self-signed certificates are nice because the machine that created them can also easily renew them, pretty much wiping out a lot of the downsides of PKI. However, we still get back to the fact that self-signed certificates essentially wipe out the whole trust model certificates are meant to create. If you trust SERVER567, then you don’t need a certificate from it, because a self-signed certificates is just a self-assertion of identity.

Notaries, however, change that picture a bit, and they’re an interesting twist on self-signed certificates. I’d argue that while a “notarized” self-signed cert isn’t truly a self signed cert anymore (because it’s been “notarized”), they’re mechanically still self-signed certificates with all the cheap ‘n’ E-Z that comes along for the ride.

If you think of a CA as a centralized trusted source of identity, a certificate notary system is akin to a decentralized system. It starts with a fun-named related activity, a Key Ceremony, which creates trust for a self-signed certificate by having existing trusted parties observe the creation of the certificate. Five “people” (it’s usually done programmatically, but let’s stick with an anthropomorphic description) who know Don Jones watch Don Jones create a self-signed certificate asserting Don Jones’ identity. A trusted “notary” counter-signs the certificate (in much the same way that a CA would counter-sign a normal certificate), and the whole transaction is logged. This isn’t a magical thing that, say, Windows already knows how to do and has just been keeping secret; you need additional software to actually go through this process.

Notaries then track the issued certificate. When you’re presented with the certificate – “Hey, this is Don Jones here, claiming to be Don Jones” – you go ask a few notaries about it. If enough say, “yeah, we know that guy, and that particular certificate is legit – people we trust watch him made it” then you accept it. The Wikipedia link above has a concise walkthrough, although the technical implementations differ a lot. For example, some notary systems are intended for internal-only use, and they operate a bit differently than one designed for us on the public Internet.

To me, this is just a different flavor of PKI – one with the stuff I’ve always wanted, like the ability for nodes to get and renew certificates on their own. In lieu of logging into a domain (like AD auto-enrollment requires), nodes’ identities are proved by other trusted entities.

Put a Pin in it

Certificate pinning is something you see in the application world most often (as opposed to online, as in SSL connections). Essentially, it means a copy of a trusted certificate is bundled into the application package, and when the application attempts an SSL connection to a back-end server, the server must present the same certificate. This helps defeat man-in-the-middle attacks where the attacker has somehow gained a copy of a trusted certificate, and can add an additional layer of trust to self-signed certificates in application scenarios. The idea is that application trusts the certificate, because the application developer told it to. Really, this is a scenario where trust and identification are no longer in play; it’s a scenario in which the certificate is being used (probably) solely for encryption between two components – a client application and a back-end server, for example – that are entirely under the developer’s control.

There’s a really good OWASP article on pinning if you’d like more detail on it (it’s a fascinating technique, and my example here is really only the simplest way it’s used).

The article’s introduction starts with a key phrase: “Secure channels.” Many people simply think “secure” means “encrypted” when it comes to communications; that’s not the case. “Secure” also has to mean, “you know who is on the other end.” We don’t think about that aspect of it very often because asymmetric encryption – which is what public/private key pairs in a certificate enable – kind of make the “who is on the other end” a no-brainer. If the wrong person is on the other end, the theory goes, they won’t have the private key needed to decrypt the communication. That doesn’t mean certificates aren’t “about” identification, though – they intrinsically are about identification, by making it impractical for someone of the wrong identity to decrypt communications (assuming you’ve done everything correctly).

Audience Context

It’s worth noting that different technology audiences have different ideas about what certificates are for – and I’m just as guilty of that as anyone, with my mainly-administrative perspective. Many developers don’t believe certificates are “about” identification at all; they see them solely as a means of securing communications between components. I disagree with that only because simply encrypting data – as I’ve written already – is no good if you don’t know who is on the other end of the encryption. An application developer might use techniques like pinning to achieve that certainty of identity, but it’s still a process of trust and identification. The OWASP article I referenced earlier actually states as much: Secure communications and identity are essentially the same problem.

It’s All About the Process

In the end, self-signed certificates are no more or less secure than any other kind of certificate; a certificate is just a bearer for a public/private key pair, really. Security comes from the process by which certificates are issued and controlled. Traditionally, CA-issued certificates have been “more secure;” as numerous prominent CAs have run into problems with their process, resulting in less-than-trustworthy certificates being issued, we’ve had to start exploring other means of creating trust. Self-signed certificates can play a role in those other processes – but it’s crucial that you recognize that security comes from process, not from the technical implementation used.

Run Makecert.exe to create a self-signed certificate for yourself, and you have no process, and therefore no trust, and therefore no security.