2

There are already answers about generating self signed certificate with openssl like this. However, what I want is a certificate that can do nothing but authenticate and encrypt the traffic to predefined websites.

A certificate generated by the following command

 openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365

has basic constraint / certificate authority set to YES, meaning that it can be used to sign other certificates. Suppose that my domain is mystackoverflow.com, an attacker who steals my private key would not only be able to MITM the connection to mystackoverflow.com, but also facebook.com or google.com because he can sign forged certificates with the said private key and get trusted by my system.

So the question is, how do I minimize the power of this certificate so that it cannot sign additional keys, sign codes, encrypt emails or do anything other than protect https connection to a specific website?

jww
  • 97,681
  • 90
  • 411
  • 885
Siyuan Ren
  • 7,573
  • 6
  • 47
  • 61
  • This question appears to be off-topic because it is not about programming or development. See [What topics can I ask about here](http://stackoverflow.com/help/on-topic) in the Help Center. Perhaps [Super User](http://superuser.com/) or [Information Security Stack Exchange](http://security.stackexchange.com/) would be a better place to ask. – jww Feb 21 '15 at 21:27
  • Sorry about the close vote. I thought it was a good question, and you got my upvote. – jww Feb 21 '15 at 21:27
  • 1
    @jww: I thought about posting on super user or security as well. But I found all sorts of similar question on SO, so I posted it here. – Siyuan Ren Feb 22 '15 at 13:54
  • I would not worry about it too much. I tend to be a little more rigid about on-topic-ness and off-topic-ness, so I move to close anything not directly related to programming or development. Programming and development Q&A is the primary goal of SO, so all question must pass that sniff test for me. The community is more tolerant, and is usually happy to give questions like this a home. – jww Feb 22 '15 at 19:12

2 Answers2

2

I want is a certificate that can do nothing but authenticate and encrypt the traffic to predefined websites... So the question is, how do I minimize the power of this certificate so that it cannot sign additional keys, sign codes, encrypt emails or do anything other than protect https connection to a specific website?

There are three parts to this question.

First is how to "authenticate and encrypt [stuff]". That's handled by Key Usage and Extended Key Usage. In particular, bits like digitalSignature (signing key exchange, like Diffie-Hellman), keyEncipherment (key transport, like RSA), serverAuth, etc.

Second is how not to mint certificates. For end entity certificates (i.e., server certificates), you remove the CA=true basic constraint and you remove the keyCertSign bits. You will still need a intermediate CA with the ability to sign end entity certificates because that's where the policy of "this CA can only issue for these names" is applied.

Third is how to apply a policy like "this CA can only issue for these names". Under the IETF's rules for PKIX in RFC 5280, you can do it in the CA certificate with the Name Constraints extension. See section 4.2.1.10 for details.

Under CA/Browser Forum rules, you can do it because they have policy objects. But I don't know how to do it under the CA/B (it may be the same as the IETF).

You have to be careful with the IETF gear. They have extensions, but they don't have policies. So you need to ensure you are working within and existing extension, and not forging new policy. See OID for certificates issued under IETF policy? on the PKIX mailing list for more details.

The CA/B Forum is significant because browsers follow the CA/B Forum rules, and not the IETF. And the CA/B Forum and IETF have different requirements in a few key areas. That's why a certificate created with OpenSSL (which follows IETF guidelines) fails to validate in Browsers (which follow CA/B Forum guidelines).


A certificate generated by the following command: openssl req ...

It used to be how to do it, but its not how to do it today. Today it produces a malformed certificate (which may or may not cause problems, depending on your user agent). For the question you cited, one answer in particular tells you why its incorrect and how to do it.

jww
  • 97,681
  • 90
  • 411
  • 885
  • I reread the question I cite, and all the answers suggest the use of `openssl req`. What did I miss? – Siyuan Ren Feb 22 '15 at 13:53
  • @Siyuan - `openssl req` will put the name in the CN, which is incorrect. You need [this answer](http://stackoverflow.com/a/27931596/608639) from the question you cited. It tells you *don't* put the name in the CN; rather, put it in the SAN. To use the SAN for names, you must use an OpenSSL CONFIG file because the command line tools lack the feature. The lack of the CONFIG file was the red flag for me. It told me you were doing things incorrectly. (You can still do things incorrectly with a CONFIG file, but that's another problem for another day ;) – jww Feb 22 '15 at 19:04
  • I accepted your answer and it may be helpful for future readers. But I decided to resort to ssh tunneling to secure my connection instead. SSH is much easier to configure, and almost impossible to open security holes, unlike custom certificates. – Siyuan Ren Feb 23 '15 at 03:37
  • @Siyuan - I think you probably made the right choice. – jww Feb 23 '15 at 23:20
1

.. an attacker who steals my private key ..

So the question is, how do I minimize the power of this certificate so that it cannot sign additional keys, sign codes, encrypt emails or do anything other than protect https connection to a specific website?

If you fear that the attacker might steal the key to the certificate and then sign other things with it, then you should not create a self-signed certificate. Instead create first your own CA. Then create a leaf-certificate which can not be used to sign certificates and sign it by your own CA. Once this is done put the private key of the CA far far away (offline or even destroy it if you don't need it to sign more certificates).

With this setup an attacker could still steal the identity of the certificate if it gets its private key. But since this certificate is not a CA itself (unlike normal self-signed certificates) it can not be used to sign new certificates.

Community
  • 1
  • 1
Steffen Ullrich
  • 114,247
  • 10
  • 131
  • 172
  • Eh, could you give a brief example of what commands I execute in order to create my own CA, leaf certificate and sign the latter with the former? I tried reading the manual of openssl, but it is very confusing. – Siyuan Ren Feb 22 '15 at 13:46
  • This was documented already a lot. Please use [google](https://www.google.de/search?q=ceate+your+own+CA+openssl). – Steffen Ullrich Feb 22 '15 at 14:16
  • I thought about signing leaf certificates too and googled before asking this question. But the various methods on the Internet seem to disagree with each other. Some uses `req` commands, some claim that `openssl req` is deprecated; some says that I need to edit some configuration file before executing commands. And some of them are using `sha1` , 1024 bit RSA keys or other insecure parameters. That is why I turn to stackoverflow for a more definite and up-to-today's-security-standards answer. – Siyuan Ren Feb 22 '15 at 15:02
  • Basically the tutorial I find on the Internet almost always contain some weak algorithms in today's world, and I don't know how many more weakness are in these tutorials. This is the problem with security; a non-professional does not have the capacity to differentiate good and bad advice. I can't just copy paste the commands and verify that it works; it works only before the weakness is actually exploited. – Siyuan Ren Feb 22 '15 at 15:14
  • The first hit I get is https://jamielinux.com/articles/2013/08/act-as-your-own-certificate-authority/ and it looks secure, i.e. uses SHA-256 and RSA 4096. It is extensive and well written, much better than I would do here. – Steffen Ullrich Feb 22 '15 at 15:20