Knowledge-Base » Historie » Verze 2
Michal Seják, 2021-03-10 21:10
1 | 1 | Jan Pašek | h1. Knowledge-Base |
---|---|---|---|
2 | |||
3 | 2 | Michal Seják | Main source of general X.509 info: https://gist.github.com/Soarez/9688998 |
4 | OCSP and certificate revocation using raw openssl: https://bhashineen.medium.com/create-your-own-ocsp-server-ffb212df8e63 |
||
5 | |||
6 | 1 | Jan Pašek | h2. X.509 certificates |
7 | |||
8 | 2 | Michal Seják | h3. What is a certificate (authority)? |
9 | |||
10 | *Certificate* = a structure belonging to a _subject_ containing his ID and public key. It is signed (= encrypted) by an _issuer_. Everyone trusts _issuer_, so by using _issuer's_ public key to decrypt the certificate, one obtains _subject's_ public key without worrying about MITM attacks. Now, whenever Alice sends data to Bob, Alice encrypts data using her private key and sends her certificate, Bob decrypts certificate using CA's public key (obtaining Alice's public key and ensuring himself Alice is actually Alice), and uses Alice's public key to decrypt Alice's data. |
||
11 | |||
12 | *Certificate authority (=CA)* = an entity capable of generating _certificates_. Must: |
||
13 | # be trusted by all communicating parties |
||
14 | # be able to fill in certificate fields according to _subject's_ needs |
||
15 | # be able to set itself as an _issuer_ of that certificate |
||
16 | # be able to encrypt the certificate by its own private key |
||
17 | # allow every communicating party to acquire its own public key (for decryption of certificates) |
||
18 | |||
19 | *Root CA* = A CA which generates its own certificate for signing "from scratch"; that is, it signs its own certificate (= self-signed certificate). |
||
20 | |||
21 | *Intermediate CA* = A CA which uses another CA to sign its certificate. |
||
22 | |||
23 | *End-entity certificate* = A certificate unable to sign other certificates. Cannot be used by CA's (as opposed to the above cases), but can be used for other purposes, such as client validation, document signature, etc. |
||
24 | |||
25 | h3. Structure (version 3) |
||
26 | |||
27 | h4. Person structure |
||
28 | |||
29 | * Country code [C] (2 capital characters, "EN", "CZ", etc.) |
||
30 | * Province [ST] (string; province/region, like "Pilsen Region") |
||
31 | * Locality [L] (string; city/town/municipality, e.g. "Pilsen") |
||
32 | * Organization [O] (string) |
||
33 | * Organizational unit [OU] (string; section name, department of org., etc.) |
||
34 | * Common name [CN] (string; a person's identifier) |
||
35 | * Email address [emailAddress] (string; that person's contact info, ideally -- an email address) |
||
36 | |||
37 | h4. Certificate structure |
||
38 | |||
39 | * Data |
||
40 | ** Version (1, 2, or 3, corresponding respectively to the RFC over which it is designed: 1422, 2459, or 5280) |
||
41 | ** Serial number (uniquely identifies certificates issued by a single CA) |
||
42 | ** Signature algorithm (how was the certificate signed, like "sha256 with RSA") |
||
43 | ** *Issuer (person)* (certificate authority, equal to subject if self-signed) |
||
44 | *** Person structure |
||
45 | ** Validity (time interval) |
||
46 | *** Not before (beginning of closed interval of validity) |
||
47 | *** Not after (end of closed interval of validity) |
||
48 | ** *Subject* (who is the certificate issued to) |
||
49 | *** Person structure |
||
50 | ** Subject public key info (certificates care only that the cipher is asymmetric) |
||
51 | *** Public key algorithm: (what the actual asymmetric implementation is) |
||
52 | **** algorithm name |
||
53 | **** key definition |
||
54 | ** *X509v3 extensions* |
||
55 | *** constraints (bool whether certificate subject is CA) |
||
56 | *** identifiers (alternative to serial numbers) of authority and subject |
||
57 | *** *key usage* (how the key will be used) |
||
58 | **** for CA -> *signing certificates & CRLs* |
||
59 | **** for end certificates -> ... |
||
60 | * Signature algorithm (again; identical as above, helps prevent substitution attacks) |
||
61 | |||
62 | |||
63 | 1 | Jan Pašek | h2. OpenSSL |
64 | 2 | Michal Seják | |
65 | * crypto library |
||
66 | * Apache (free for commertial purposes) |
||
67 | |||
68 | * CLI (awkward calls) |
||
69 | <pre><code class="python"> |
||
70 | os.system("openssl ...") |
||
71 | subprocess.run("openssl ...", input=bytes(...)) |
||
72 | </code></pre> |
||
73 | |||
74 | * *very fast* - proud enough to include benchmarks in command set. Declares certificates and certificate authorities very quickly (basic setup including end certificate takes 100-200 ms) |
||
75 | |||
76 | Example usage (key generation): |
||
77 | <pre><code class="python"> |
||
78 | def make_private_key(name, passphrase): |
||
79 | subprocess.run(["openssl", "genrsa", "-des3", "-out", name + ".key", "2048"], |
||
80 | input=bytes(f'{passphrase}\n{passphrase}\n', encoding='utf-8')) |
||
81 | </code></pre> |
||
82 | |||
83 | The code is not very readable, but can be formatted in the following way to add readability: |
||
84 | <pre><code class="python"> |
||
85 | subprocess.run(["openssl", |
||
86 | "genrsa", # generate a private key for RSA encryption scheme |
||
87 | "-des3", # use DES3 for encryption by passphrase |
||
88 | "-out", f"{name}.key", # output specification |
||
89 | "2048"], # bits |
||
90 | |||
91 | input=bytes( # input required to interact with openssl's CLI |
||
92 | f'{passphrase}\n' # openssl queries for passphrase, respond and return |
||
93 | f'{passphrase}\n', # openssl queries for passphrase verification, respond and return |
||
94 | encoding='utf-8') # use standard encoding for input stream |
||
95 | ) |
||
96 | </code></pre> |
||
97 | |||
98 | * vast amount of customization & config files, while pretty straightforward and easy to use if special features and customization deemed unnecessary |
||
99 | * contains bugs that users must handle (e.g. entering an incorrect password causes the program to fail checking of future passwords regardless of their correctness) |
||
100 | * overall handling of "return values" must be parsed from openssl's stdout, which can be a nuisance |
||
101 | * however, we can safely estimate the upper bound for the amount of unique openssl commands we will have to call to be 10 (CA creation, certificate sign/revoke, key creation, crl, ocsp, ...), |
||
102 | which have predictable output formats |
||
103 | * huge documentation at our disposal |
||
104 | * implicitly defaults certain variables to smart values, e.g. allows keys to be generated randomly without explicitly specifying details about exponents in RSA |
||
105 | |||
106 | h2. cryptography (Python lib) |
||
107 | |||
108 | * crypto library |
||
109 | * low-level OpenSSL utility |
||
110 | * very well documented |
||
111 | * tutorials |
||
112 | * contains useful pre-implemented classes, like Certificate and CertificateIssuer, but these will have to be extended in order to be linked together in a tree structure |
||
113 | * however, it seems to have been designed with ease-of-use and OOP in mind as opposed to performance; overly complex design patterns like Builder, performs a multitude of actions and function calls before actually calling the backend (= openssl); this causes the same result achieved by openssl to arrive about 2x slower |
||
114 | * if raw openssl calls are formatted in the way specified above, it uses cca the same amount of lines of code while being more readable, but larger |
||
115 | |||
116 | This tutorial code is perhaps slightly more readable than raw openssl calls. |
||
117 | <pre><code class="python"> |
||
118 | key = rsa.generate_private_key( |
||
119 | public_exponent=65537, |
||
120 | key_size=2048, |
||
121 | ) |
||
122 | with open("cert/key.pem", "wb") as f: |
||
123 | f.write(key.private_bytes( |
||
124 | encoding=serialization.Encoding.PEM, |
||
125 | format=serialization.PrivateFormat.TraditionalOpenSSL, |
||
126 | encryption_algorithm=serialization.BestAvailableEncryption(b"passphrase"), |
||
127 | )) |
||
128 | </code></pre> |
||
129 | |||
130 | * depends on *cffi*, which depends on *pycparser* -> three new libraries are required to be installed on the target machine |