An open API service indexing awesome lists of open source software.

https://github.com/aprilahijriyan/certpy

Self-signed SSL certificate generator :closed_lock_with_key:
https://github.com/aprilahijriyan/certpy

https openssl self-signed-certificate

Last synced: 2 months ago
JSON representation

Self-signed SSL certificate generator :closed_lock_with_key:

Awesome Lists containing this project

README

          

# certpy

> Self-signed SSL certificate generator :closed_lock_with_key:

This tool is an experiment to learn _"How to create a self-signed certificate"_.

## Installation

With `pip`:

```
pip install certpy
```

Install from source (you need to install [python-pdm](https://pdm.fming.dev/latest/) first):

```
git clone https://github.com/aprilahijriyan/certpy.git
cd certpy
pdm install
```

## Usage

CertPy provides a workflow file, which will be used to instruct the creation of the certificate.

> The workflow file name is `certpy.yml` (you cannot change the file name or extension to `.yaml`) and the workflow file must be in the directory you are working in.

Here's an example of a workflow:

```yml
# Save it as certpy.yml in the current directory.
certificate_age: &age
days: 365

certificates:
kuli:
type: ca
distinguished_name:
countryName: ID
stateOrProvinceName: Indonesia
localityName: Jawa Barat
organizationName: Kuli Dev
organizationalUnitName: OSS
commonName: Kuli Dev Root CA
emailAddress: null
age: *age
hash: sha256
overwrite: true

server:
type: server
distinguished_name:
commonName: Server
ca_file: kuli
age: *age
hash: sha256
san:
ip:
- 192.168.18.203
dns:
- ca.example.com
overwrite: true

client:
type: client
distinguished_name:
commonName: Client
ca_file: kuli
age: *age
hash: sha256
overwrite: true
```

Then, create a CertPy environment (this is to hold all certificates created by CertPy).

```sh
# this will create a `~/.certpy` directory and create a default `Root CA` certificate stored in `~/.certpy/ca/certs/rootCA.pem`.
certpy ca init
```

Now you can create your own certificate from the workflow file!

```
$ certpy create
'kuli' Root CA
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ CA File ┃ CA Key ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ /home/april/.certpy/ca/certs/kuli.pem │ /home/april/.certpy/ca/private/kuli.key │
└───────────────────────────────────────┴─────────────────────────────────────────┘
'server' Certificate
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Cert File ┃ Cert Key ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ /home/april/.certpy/server/certs/server.pem │ /home/april/.certpy/server/private/server.key │
└─────────────────────────────────────────────┴───────────────────────────────────────────────┘
'client' Certificate
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Cert File ┃ Cert Key ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ /home/april/.certpy/client/certs/client.pem │ /home/april/.certpy/client/private/client.key │
└─────────────────────────────────────────────┴───────────────────────────────────────────────┘
```

You can verify the self-signed certificate, using the command:

```
$ openssl verify -verbose -CAfile /home/april/.certpy/ca/certs/kuli.pem /home/april/.certpy/server/certs/server.pem
/home/april/.certpy/server/certs/server.pem: OK
```

All certificates generated by CertPy will be stored in the `~/.certpy` directory. And each type of certificate is stored in a different directory.

* For `Root CA` stored in `~/.certpy/ca`.
* For `Server Certificate` stored in `~/.certpy/server`.
* For `Client Certificate` stored in `~/.certpy/client`.

In the directory `~/.certpy/{ca,server,client}` there are 2 directories.

* The `certs` directory is used to store certificates.
* The `private` directory is used to store certificate keys.

## Workflow structure details

* About `certificates` in workflow file

It contains the definition of certificate.
In CertPy only supports `Root CA`, `Server` and `Client` certificate types.

Each type of certificate has a different data structure. Read more below...

* About `Root CA` Certificate

The structure for `Root CA` is as follows:

* `type`: set to `ca` to mark if this is a **Root CA** certificate. (**required**)
* `distinguished_name`: (`object`, **required**)

* `countryName`: Country Code (e.g. `ID`) (**optional**)
* `stateOrProvinceName`: State (e.g. `Indonesia`) (**optional**)
* `localityName`: Province (e.g. `Jawa Barat`) (**optional**)
* `organizationName`: Organization Name (e.g. `Kuli Dev`) (**optional**)
* `organizationalUnitName`: Organization Unit Name (e.g. `OSS`) (**optional**)
* `commonName`: Common Name (e.g. `Kuli Dev Root CA`) (**required**)
* `emailAddress`: Email address (e.g. `your@company.com`) (**optional**)
* `age`: (`object`, **required**)

You must fill in one of the fields below. For example fill `days` with `365` (which is a certificate valid in 1 year)

* `days`
* `seconds`
* `microseconds`
* `milliseconds`
* `minutes`
* `hours`
* `weeks`

* `hash`: See https://www.pyopenssl.org/en/latest/api/crypto.html#digest-names (**required**)
* `overwrite`: If it is set to `true` it will overwrite the old certificate with the new one. By default, if the certificate already exists it will be skipped. (`bool`, **optional**)

* About `Server` Certificate

Its structure is the same as `Root CA`.

However, there is a slight addition to the `Server` certificate. Here's a list of the new fields in the `server` certificate:

* `ca_file`: (`str` or `array`, **required**)

The CA file is required to sign certificates for `server` or `client`.

- If it is `str`, it will use the `Root CA` certificate from the workflow file.
- If using `array`, must have 2 items. For example index `0` is `CA File` and index `1` is `CA Key`.

* `san`: (`object`, **required**)

* `ip`: IP address list (`array`)
* `dns`: Domain name list (`array`)

> Note: the certificate must be marked with `type: server` if you want to create a certificate for `Server`.

* About `Client` Certificate

Its structure is the same as `Server Certificate`.

However, on the client certificate it doesn't have a `san` field.

> Note: the certificate must be marked with `type: client` if you want to create a certificate for `Client`.

## Related projects

CertPy is heavily inspired by the following tools:

* [mkcert](https://github.com/FiloSottile/mkcert)
* [step-cli](https://smallstep.com/)