GnuTLS — это программная библиотека для работы с SSL/TLS и сертификатами. Она может примерно то же, что и openssl, но разрабатывается независимо. Аналогично в составе gnutls есть набор консольных программ для работы с сертификатами, протоколами и прочими данными: certtool, gnutls-serv, gnutls-cli и т.д.
В плане работы с файлами сертификатов, ключей и CSR-запросов утилиты gnutls умеют делать практически то же самое, что и бинарник openssl. В этой статье я детально опишу типичные сценарии использования: создание ключей, сертификатов, запросов на сертификат, подписывание сертификатов.
Другие мои статьи на эту тему, но на базе openssl:
Certtool входит в состав gnutls и в debian/ubuntu ставится командой:
$ sudo apt install gnutls-bin
На макоси gnutls ставится через Homebrew:
$ brew install gnutls
Создаём самоподписанный сертификат¶
Задача. Создать простейший тестовый самоподписанный сертификат для использования в веб-сервере в качестве сертификата для сайта example.regolit.com
.
Сначала создаём секретный ключ (4096 бит, сохраняем в файл privkey.pem
):
$ certtool --generate-privkey --bits 4096 --outfile privkey.pem
** Note: You may use '--sec-param High' instead of '--bits 4096'
Generating a 4096 bit RSA private key...
$
Или в сокращённой форме (вместо --generate-privkey
можно писать -p
):
$ certtool -p --bits 4096 --outfile privkey.pem
Затем создаём сертификат на базе ключа из файла privkey.pem
и запишем его в файл example.regolit.com.pem
:
$ certtool --generate-self-signed --load-privkey privkey.pem --outfile example.regolit.com.pem
Generating a self signed certificate...
Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
Common name: bla-bla-bla
UID:
Organizational unit name: Management
Organization name: Regolit
Locality name: Novosibirsk
State or province name:
Country name (2 chars): RU
Enter the subject's domain component (DC):
This field should not be used in new certificates.
E-mail:
Enter the certificate's serial number in decimal (default: 6605742564817393062):
Activation/Expiration time.
The certificate will expire in (days): 365
Extensions.
Does the certificate belong to an authority? (y/N):
Is this a TLS web client certificate? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Is this a TLS web server certificate? (y/N): y
Enter a dnsName of the subject of the certificate: example.regolit.com
Enter a dnsName of the subject of the certificate:
Enter a URI of the subject of the certificate:
Enter the IP address of the subject of the certificate:
Will the certificate be used for signing (DHE ciphersuites)? (Y/n):
Will the certificate be used for encryption (RSA ciphersuites)? (Y/n):
Will the certificate be used to sign OCSP requests? (y/N):
Will the certificate be used to sign code? (y/N):
Will the certificate be used for time stamping? (y/N):
Will the certificate be used for email protection? (y/N):
Enter the URI of the CRL distribution point:
.......
Is the above information ok? (y/N): y
Signing certificate...
Как вы могли заметить, certtool
запускается в интерактивном режиме и задаёт очень много вопросов о назначении сертификата, в зависимости от ваших ответов будут выбраны нужные значения для расширений (extensions) либо расширения совсем не будут включены в сертификат.
На вопрос Does the certificate belong to an authority? (y/N): был выбран ответ по умолчанию (N), поэтому в сертификат было включено явное ограничение на использование сертификата в качестве CA.
На вопрос Common name я указал строку bla-bla-bla вместо домена, поскольку в современных браузерах поле commonName сертификата не используется для идентификации домена, вместо этого используется расширение subjectAltName (SAN).
Создание сертификата в неинтерактивном режиме¶
Существует также режим, в котором нужные значения передаются через файл-шаблон.
Сначала создаём файл cert.cfg
со следующим содержимым (вы можете скачать его):
organization = "Regolit Inc."
locality = "Novosibirsk"
state = NSO
country = RU
# common name
cn = "Example web site"
serial = 123456789
expiration_days = 366
# subjectAltNames
dns_name = example.regolit.com
$ certtool --generate-self-signed --load-privkey privkey.pem --outfile example.regolit.com.pem --template cert.cfg
Generating a self signed certificate...
X.509 Certificate Information:
Version: 3
........
Signing certificate...
И создаём сертификат с использованием шаблона:
$ certtool --generate-self-signed --load-privkey privkey.pem --outfile example.regolit.com.pem --template cert.cfg
В шаблоне можно указать всякие разные параметры сертификата, включая конкретные даты выписывания и окончания, например. Все они описаны в официальной документации certtool в разделе Certtool’s template file format.
Просмотр сертификата¶
Через certtool можно также распечатать подробную информацию о сертификате.
$ certtool -i --infile example.regolit.com.pem
X.509 Certificate Information:
Version: 3
Serial Number (hex): 5bac4fdd2d9e55a6
Issuer: C=RU,L=Novosibirsk,O=Regolit,OU=Management,CN=bla-bla-bla
Validity:
Not Before: Thu Sep 27 03:34:55 UTC 2018
Not After: Fri Sep 27 03:35:00 UTC 2019
Subject: C=RU,L=Novosibirsk,O=Regolit,OU=Management,CN=bla-bla-bla
...... skipped
Также сертификат можно передать в stdin:
$ certtool -i < example.regolit.com.pem
Аналогичная команда через openssl:
$ openssl x509 -in example.regolit.com.pem -noout -text
Создание корневого сертификата для Certification Authority¶
Корневой сертификат Certification Authority (CA) — это самоподписанный сертификат с установленным разрешённым расширением Certificate Authority (CA): TRUE. Он создаётся по той же схеме, что и обычный самоподписанный сертификат, но на вопрос Does the certificate belong to an authority? (y/N): необходимо ответить Y. Также для сертификата CA не имеет особого смысла расширение subjectAltName.
Создаём новый секретный ключ и записываем его в файл cakey.pem
:
$ certtool --generate-privkey --bits 4096 --outfile cakey.pem
** Note: You may use '--sec-param High' instead of '--bits 4096'
Generating a 4096 bit RSA private key...
И создаём сертификат, на вопрос Does the certificate belong to an authority? (y/N): отвечаем Y:
$ certtool --generate-self-signed --load-privkey cakey.pem --outfile cacert.pem
Generating a self signed certificate...
Please enter the details of the certificate's distinguished name. Just press enter to ignore a field.
Common name: Testing Certification Authority
UID:
Organizational unit name:
Organization name: Regolit
Locality name:
State or province name:
Country name (2 chars): RU
Enter the subject's domain component (DC):
This field should not be used in new certificates.
E-mail:
Enter the certificate's serial number in decimal (default: 6605781558298122568):
Activation/Expiration time.
The certificate will expire in (days): 3600
Extensions.
Does the certificate belong to an authority? (y/N): y
Path length constraint (decimal, -1 for no constraint): -1
Is this a TLS web client certificate? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Is this a TLS web server certificate? (y/N):
Enter a dnsName of the subject of the certificate:
Enter a URI of the subject of the certificate:
Enter the IP address of the subject of the certificate:
Enter the e-mail of the subject of the certificate:
Will the certificate be used to sign OCSP requests? (y/N):
Will the certificate be used to sign code? (y/N):
Will the certificate be used for time stamping? (y/N):
Will the certificate be used for email protection? (y/N):
Will the certificate be used to sign other certificates? (y/N):
Will the certificate be used to sign CRLs? (y/N):
Enter the URI of the CRL distribution point:
X.509 Certificate Information:
.......
Signing certificate...
Создание Certificate Signing Request (CSR)¶
Создание CSR во многом напоминает создание сертификата: вам тоже нужно ответить на кучу вопросов или воспользоваться файлом-шаблоном. Однако в отличие от сертификата, секретный ключ можно сгенерировать автоматически в том же самом вызове. Этот секретный ключ будет либо напечатан на экране, либо выведен в файл, указанный в аргументе --outfile
.
Я буду создавать по отдельности секретный ключ и запрос. Сначала ключ:
$ certtool --generate-privkey --bits 4096 --outfile domain.key.pem
** Note: You may use '--sec-param High' instead of '--bits 4096'
Generating a 4096 bit RSA private key...
$
Теперь создаём CSR:
$ certtool --generate-request --load-privkey domain.key.pem --outfile domain.csr.pem
Generating a PKCS #10 certificate request...
Common name: Example Web Site
Organizational unit name:
Organization name:
Locality name:
State or province name:
Country name (2 chars): RU
Enter the subject's domain component (DC):
UID:
Enter a dnsName of the subject of the certificate: example.com
Enter a dnsName of the subject of the certificate:
Enter a URI of the subject of the certificate:
Enter the IP address of the subject of the certificate:
Enter the e-mail of the subject of the certificate:
Enter a challenge password:
Does the certificate belong to an authority? (y/N):
Will the certificate be used for signing (DHE ciphersuites)? (Y/n):
Will the certificate be used for encryption (RSA ciphersuites)? (Y/n):
Will the certificate be used to sign code? (y/N):
Will the certificate be used for time stamping? (y/N):
Will the certificate be used for email protection? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Will the certificate be used to sign OCSP requests? (y/N):
Is this a TLS web client certificate? (y/N):
Is this a TLS web server certificate? (y/N):
Посмотреть содержимое файла с CSR можно командой:
$ certtool --crq-info < domain.csr.pem
Создание сертификата через CSR и его подписывание CA¶
Создание сертификата на основе CSR, сертификата CA и секретного ключа CA.
$ certtool --generate-certificate --load-request domain.csr.pem --load-ca-certificate cacert.pem --load-ca-privkey cakey.pem --outfile domain.cert.pem
Generating a signed certificate...
Enter the certificate's serial number in decimal (default: 6605789709969658106):
Activation/Expiration time.
The certificate will expire in (days): 365
Extensions.
Do you want to honour all the extensions from the request? (y/N): y
Does the certificate belong to an authority? (y/N):
Is this a TLS web client certificate? (y/N):
Will the certificate be used for IPsec IKE operations? (y/N):
Is this a TLS web server certificate? (y/N): y
Enter a dnsName of the subject of the certificate:
Enter a URI of the subject of the certificate:
Enter the IP address of the subject of the certificate:
Will the certificate be used for signing (DHE ciphersuites)? (Y/n):
Will the certificate be used for encryption (RSA ciphersuites)? (Y/n):
Will the certificate be used to sign OCSP requests? (y/N):
Will the certificate be used to sign code? (y/N):
Will the certificate be used for time stamping? (y/N):
Will the certificate be used for email protection? (y/N):
X.509 Certificate Information:
Version: 3
... skipped
Signing certificate...
На вопрос Do you want to honour all the extensions from the request? (y/N): отвечаем Y, это означает, что мы автоматически в сертификат включаем все указанные расширения из CSR (у нас это пока только subjectAltName).
Проверка подписи сертификата через сертификат CA¶
Задача. На входе сертификат домена (domain.cert.pem
) и сертификат CA (cacert.pem
).
$ certtool --verify --load-ca-certificate cacert.pem --infile domain.cert.pem
Loaded 1 certificates, 1 CAs and 0 CRLs
Subject: C=RU,CN=Example Web Site
Issuer: C=RU,O=Regolit,CN=Testing Certification Authority
Checked against: C=RU,O=Regolit,CN=Testing Certification Authority
Output: Verified. The certificate is trusted.
Chain verification output: Verified. The certificate is trusted.
Ну и для примера результат проверки для ранее созданного самоподписанного сертификата example.regolit.com.pem
:
$ certtool --verify --load-ca-certificate cacert.pem --infile example.regolit.com.pem
Loaded 1 certificates, 1 CAs and 0 CRLs
Subject: C=RU,ST=NSO,L=Novosibirsk,O=Regolit Inc.,CN=Example web site
Issuer: C=RU,ST=NSO,L=Novosibirsk,O=Regolit Inc.,CN=Example web site
Output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.
Chain verification output: Not verified. The certificate is NOT trusted. The certificate issuer is unknown.