Expertus metuit
Работа с сертификатами через gnutls/certtool
2018-09-27 10:00

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. 

Комментарии

Текст комментария (разметка: *курсив*, **полужирная**, [ссылка](http://example.com) или <http://example.com> ещё)
Имя (обязательно, 50 символов или меньше)
Опциональный email, на который получать ответы (не будет опубликован)
Веб-сайт
© 2006—2018 Sergey Stolyarov | Работает на Pyrone