blob: 0fa061a2f01f7a456cde2bebfd0c0e8f6a111ef8 [file] [log] [blame]
Alex Gaynor11b00cd2015-07-13 21:12:39 -04001Tutorial
2========
3
4X.509 certificates are used to authenticate clients on servers. The most common
Alex Gaynor0c91ddc2015-07-13 21:15:03 -04005use case is for web servers using HTTPS.
Alex Gaynor11b00cd2015-07-13 21:12:39 -04006
7Creating a Certificate Signing Request (CSR)
8--------------------------------------------
9
10When obtaining a certificate from a certificate authority (CA), the usual
Alex Gaynor0c91ddc2015-07-13 21:15:03 -040011flow is:
Alex Gaynor11b00cd2015-07-13 21:12:39 -040012
131. You generate a private/public key pair.
Alex Gaynor5bcd8e82015-07-13 21:17:31 -0400142. You create a request for a certificate, which is signed by your key (to
15 prove that you own that key).
Alex Gaynor11b00cd2015-07-13 21:12:39 -0400163. You give your CSR to a CA (but *not* the private key).
174. The CA validates that you own the resource (e.g. domain) you want a
18 certificate for.
Alex Gaynor5bcd8e82015-07-13 21:17:31 -0400195. The CA gives you a certificate, signed by them, which identifies your public
Alex Gaynor11b00cd2015-07-13 21:12:39 -040020 key, and the resource you are authenticated for.
Alex Gaynor5bcd8e82015-07-13 21:17:31 -0400216. You configure your server to use that certificate, combined with your
22 private key, to server traffic.
Alex Gaynor11b00cd2015-07-13 21:12:39 -040023
24If you want to obtain a certificate from a typical commercial CA, here's how.
25First, you'll need to generate a private key, we'll generate an RSA key (these
26are the most common types of keys on the web right now):
27
28.. code-block:: pycon
29
30 >>> from cryptography.hazmat.backends import default_backend
31 >>> from cryptography.hazmat.primitives import serialization
32 >>> from cryptography.hazmat.primitives.asymmetric import rsa
33 >>> # Generate our key
34 >>> key = rsa.generate_private_key(
35 ... public_exponent=65537,
36 ... key_size=2048,
37 ... backend=default_backend()
38 ... )
39 >>> # Write our key to disk for safe keeping
Tim Buchwaldte7820612015-08-26 19:15:03 +020040 >>> with open("path/to/store/key.pem", "wb") as f:
Alex Gaynor11b00cd2015-07-13 21:12:39 -040041 ... f.write(key.private_bytes(
42 ... encoding=serialization.Encoding.PEM,
43 ... format=serialization.PrivateFormat.TraditionalOpenSSL,
44 ... encryption_algorithm=serialization.BestAvailableEncryption(b"passphrase"),
Alex Gaynord02bc122015-07-13 21:18:56 -040045 ... ))
Alex Gaynor11b00cd2015-07-13 21:12:39 -040046
47If you've already generated a key you can load it with
Alex Gaynor9ca48512015-07-16 07:03:40 -040048:func:`~cryptography.hazmat.primitives.serialization.load_pem_private_key`.
Alex Gaynor11b00cd2015-07-13 21:12:39 -040049
Alex Gaynor5bcd8e82015-07-13 21:17:31 -040050Next we need to generate a certificate signing request. A typical CSR contains
51a few details:
Alex Gaynor11b00cd2015-07-13 21:12:39 -040052
53* Information about our public key (including a signature of the entire body).
54* Information about who *we* are.
55* Information about what domains this certificate is for.
56
57.. code-block:: pycon
58
59 >>> from cryptography import x509
Paul Kehrer246daf72015-08-10 21:12:24 -050060 >>> from cryptography.x509.oid import NameOID
Abhijeet Rastogia5e999a2015-08-15 08:44:14 +053061 >>> from cryptography.hazmat.primitives import hashes
Alex Gaynor11b00cd2015-07-13 21:12:39 -040062 >>> # Generate a CSR
63 >>> csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
64 ... # Provide various details about who we are.
Paul Kehrer246daf72015-08-10 21:12:24 -050065 ... x509.NameAttribute(NameOID.COUNTRY_NAME, u"US"),
66 ... x509.NameAttribute(NameOID.STATE_OR_PROVINCE_NAME, u"CA"),
67 ... x509.NameAttribute(NameOID.LOCALITY_NAME, u"San Francisco"),
68 ... x509.NameAttribute(NameOID.ORGANIZATION_NAME, u"My Company"),
69 ... x509.NameAttribute(NameOID.COMMON_NAME, u"mysite.com"),
Alex Gaynorf6487342015-09-03 10:10:49 -040070 ... ])).add_extension(
71 ... x509.SubjectAlternativeName([
72 ... # Describe what sites we want this certificate for.
73 ... x509.DNSName(u"mysite.com"),
74 ... x509.DNSName(u"www.mysite.com"),
75 ... x509.DNSName(u"subdomain.mysite.com"),
76 ... ]),
77 ... critical=False,
Alex Gaynor11b00cd2015-07-13 21:12:39 -040078 ... # Sign the CSR with our private key.
Alex Gaynorf6487342015-09-03 10:10:49 -040079 ... ).sign(key, hashes.SHA256(), default_backend())
Alex Gaynor11b00cd2015-07-13 21:12:39 -040080 >>> # Write our CSR out to disk.
Tim Buchwaldte7820612015-08-26 19:15:03 +020081 >>> with open("path/to/csr.pem", "wb") as f:
Alex Gaynor11b00cd2015-07-13 21:12:39 -040082 ... f.write(csr.public_bytes(serialization.Encoding.PEM))
83
84Now we can give our CSR to a CA, who will give a certificate to us in return.