blob: 565b6d3fcfbc9046f1b0dca448a69666c2244a7c [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
5use case is for webservers using HTTPS.
6
7Creating a Certificate Signing Request (CSR)
8--------------------------------------------
9
10When obtaining a certificate from a certificate authority (CA), the usual
11workflow is:
12
131. You generate a private/public key pair.
142. You create a request for a certificate, which is signed by your key (to prove
15 that you own that key).
163. 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.
195. The CA gives you a certificate, signed by them. Which identifies your public
20 key, and the resource you are authenticated for.
21
22If you want to obtain a certificate from a typical commercial CA, here's how.
23First, you'll need to generate a private key, we'll generate an RSA key (these
24are the most common types of keys on the web right now):
25
26.. code-block:: pycon
27
28 >>> from cryptography.hazmat.backends import default_backend
29 >>> from cryptography.hazmat.primitives import serialization
30 >>> from cryptography.hazmat.primitives.asymmetric import rsa
31 >>> # Generate our key
32 >>> key = rsa.generate_private_key(
33 ... public_exponent=65537,
34 ... key_size=2048,
35 ... backend=default_backend()
36 ... )
37 >>> # Write our key to disk for safe keeping
38 >>> with open("path/to/store/key.pem") as f:
39 ... f.write(key.private_bytes(
40 ... encoding=serialization.Encoding.PEM,
41 ... format=serialization.PrivateFormat.TraditionalOpenSSL,
42 ... encryption_algorithm=serialization.BestAvailableEncryption(b"passphrase"),
43 ... ))
44
45If you've already generated a key you can load it with
46:func:`~cryptography.hazmat.primitives.serialization.load_pem_public_key`.
47
48Next we need to generate a certificate signing request. A typical CSR contains a
49few details:
50
51* Information about our public key (including a signature of the entire body).
52* Information about who *we* are.
53* Information about what domains this certificate is for.
54
55.. code-block:: pycon
56
57 >>> from cryptography import x509
58 >>> # Generate a CSR
59 >>> csr = x509.CertificateSigningRequestBuilder().subject_name(x509.Name([
60 ... # Provide various details about who we are.
61 ... x509.NameAttribute(x509.OID_COUNTRY_NAME, u"US"),
62 ... x509.NameAttribute(x509.OID_STATE_OR_PROVINCE_NAME, u"CA"),
63 ... x509.NameAttribute(x509.OID_LOCALITY_NAME, u"San Francisco"),
64 ... x509.NameAttribute(x509.OID_ORGANIZATION_NAME, u"My Company"),
65 ... x509.NameAttribute(x509.COMMON_NAME, u"mysite.com"),
66 ... ])).add_extension(x509.SubjectAlternativeName([
67 ... # Describe what sites we want this certificate for.
68 ... x509.DNSName(u"mysite.com"),
69 ... x509.DNSName(u"www.mysite.com"),
70 ... x509.DNSName(u"subdomain.mysite.com"),
71 ... # Sign the CSR with our private key.
72 ... ])).sign(key, hashes.SHA256(), default_backend())
73 >>> # Write our CSR out to disk.
74 >>> with open("path/to/csr.pem") as f:
75 ... f.write(csr.public_bytes(serialization.Encoding.PEM))
76
77Now we can give our CSR to a CA, who will give a certificate to us in return.