OpenSSL и Network Security Services (NSS) — две стороны одной медали

imageО какой медали идет речь в заголовке? Речь идет об инфраструктуре открытых ключей (Public Key Infrastructure — PKI/ИОК) на базе стандартов криптографии с открытым ключом (Public Key Cryptography Standards — PKCS). Инфраструктура открытых ключей включает в себя множество различных объектов и механизмов работы с ними, а также протоколы взаимодействия объектов друг с другом (например, протоколы TLS, OCSP). В число объектов ИОК/PKI входят сертификаты x509 и ключевые пары (приватные и публичные ключи), подписанные и зашифрованные документы (pkcs#7, CMS). защищенные контейнеры для хранения приватных ключей (pkcs#8) и личных сертификатов с ключами (pkcs#12) и т.д. В число механизмов входят не только криптографические функции, которые позволяют шифровать и подписывать документы по различным алгоритмам, но и функции формирующие конечные объекты ИОК в соответствии со стандартами (сертификаты, запросы, подписанные/зашифрованные документы, пакеты протоколов и т.д. и т.п.). Да, и как не вспомнить центральный объект ИОК/PKI — Удостоверяющий Центр (УЦ).
Рядовой пользователь интернет использует различные механизмы и объекты ИОК/PKI, не подозревая того, когда использует протокол HTTPS при доступе к различным сайтам, когда подписывает и/или шифрует свои электронные письма или использует электронную подпись в документообороте.
Наиболее продвинутыми средствами для создания инфраструктуры открытых ключей, программных средств, работающих в составе PKI/ИОК, являются OpenSSL и Network Security Services (NSS).
OpenSSL — набор полноценных криптографических библиотек и утилиты с открытым исходным кодом, которые поддерживает почти все низкоуровневые алгоритмы хеширования, шифрования и электронной подписи, а также реализует большинство популярных криптографических стандартов, в том числе: позволяет создавать ключи RSA, DH, DSA, EC, выпускать сертификаты X.509, шифровать и подписывать данные и создавать SSL/TLS соединения.
Следует отметить, что объекты, с которыми работает утилита OpenSSL, хранятся в файлах (сертификаты, ключи).
Таким же набором полноценных криптографических библиотек и утилит с открытым исходным кодом является и Network Security Services (NSS).
Основное отличие OpenSSL от NSS заключается в том, что OpenSSL, предполагает, что сертификаты и ключи хранятся в файлах, а NSS для хранения сертификатов и ключей использует базы данных и токены PKCS#11.
Самым существенным является то, что оба проекта (OpenSSL и NSS) строго придерживаются стандартов и поэтому не возникает проблем при их совместном использовании в различных проектах. Таким хорошим примером их содружества может служить, например, применение протокола HTTPS, когда сайты/порталы строятся на базе Apache с mod_ssl на базе OpenSSL, а доступ к ним ведется, например, посредством Firefox, в котором поддержка TLS 1.0/TLS 1.2 и TLS 1.3 осуществляется с помощью библиотек NSS.
Ниже будет показано как утилиты OpenSSL и NSS могут использоваться для решения одних и тех же задач. В дальнейшем каждый может использовать утилиты по своему вкусу. Познакомиться с библиотечными функциями каждый может просмотрев исходный код той или иной утилиты.

Просмотр сертификатов и других сущностей, хранящихся в файлах


В пакете OpenSSL присутствует одна утилита — openssl, первым параметром в которой задается собственно команда (Standard commands), которую необходимо выполнить:

$openssl help
Standard commands
asn1parse         ca                ciphers           cms               
crl               crl2pkcs7         dgst              dhparam           
dsa               dsaparam          ec                ecparam           
enc               engine            errstr            exit              
gendsa            genpkey           genrsa            help              
list              nseq              ocsp              passwd            
pkcs12            pkcs7             pkcs8             pkey              
pkeyparam         pkeyutl           prime             rand              
rehash            req               rsa               rsautl            
s_client          s_server          s_time            sess_id           
smime             speed             spkac             srp               
ts                verify            version           x509              

Message Digest commands (see the `dgst' command for more details)
blake2b512        blake2s256        gost              md2               
md4               md5               rmd160            sha1              
sha224            sha256            sha384            sha512            

Cipher commands (see the `enc' command for more details)
aes-128-cbc       aes-128-ecb       aes-192-cbc       aes-192-ecb       
aes-256-cbc       aes-256-ecb       base64            bf                
bf-cbc            bf-cfb            bf-ecb            bf-ofb            
camellia-128-cbc  camellia-128-ecb  camellia-192-cbc  camellia-192-ecb  
camellia-256-cbc  camellia-256-ecb  cast              cast-cbc          
cast5-cbc         cast5-cfb         cast5-ecb         cast5-ofb         
des               des-cbc           des-cfb           des-ecb           
des-ede           des-ede-cbc       des-ede-cfb       des-ede-ofb       
des-ede3          des-ede3-cbc      des-ede3-cfb      des-ede3-ofb      
des-ofb           des3              desx              idea              
idea-cbc          idea-cfb          idea-ecb          idea-ofb          
rc2               rc2-40-cbc        rc2-64-cbc        rc2-cbc           
rc2-cfb           rc2-ecb           rc2-ofb           rc4               
rc4-40            rc5               rc5-cbc           rc5-cfb           
rc5-ecb           rc5-ofb           seed              seed-cbc          
seed-cfb          seed-ecb          seed-ofb          zlib              
$ 


Как можно заметить, при выполнении команды openssl help, помимо собственно перечня команд, выводится список поддерживаемых хэш-алгоритмов и алгоритмов шифрования (в их перечень включены и функции сжатия и работы с base64).
Для просмотра сертификата (x509), запроса (req) или списка отозванных сертификатов (crl) достаточно выполнить команду следующего вида:
openssl x509[|req|crl] [-nameopt utf8] -inform PEM|DER -noout -in .
Например, команда:

$openssl x509 -text -nameopt utf8 -inform PEM -noout -in cert.pem


отобразит на экране компьютера содержимое сертификата в техтовом виде (x509 -text), хранящегося в файле cert.pem (-in cert.pem) в кодировке PEM (base64) (-inform PEM) и содержащего символы в кодировке utf-8 (-nameopt utf8). При этом сам сертификат в кодировке PEM на экран выводиться не будет (-noout).
В пакете NSS аналогичные действия выполняет утилита pp.
Утилита pp — это утилита элегантной печати (Pretty Print) файла, содержащего ASN.1 структуру в DER или PEM-кодировки:

Usage:  pp [-t type] [-a] [-i input] [-o output] [-w] [-u],  

где type:

  • с — сертификат;
  • cr — запрос на сертификат;
  • pk — публичный ключ;
  • pk — файл с открытым ключом;
  • crl — списоk отозванных сертификатов.


Отметим еще один тип, который применяется к сертификатам, ci (certificate-identity). Этот тип позволяет получить из сертификата идентифицирующую его информацию, такую как subject (владелец), issuer (издатель), serial number (серийный номер), fingerprint (отпечатки по SHA-1 и SHA-256). Аналогичные параметры есть и в утилиты openssl для x509.
По умолчанию предполагается, что все объекты находятся в DER-кодировке. Если же объекты находятся в PEM-кодировке то необходимо задать параметр »-a» (аналог параметра »-inform PEM» для утилиты openssl). И еще один параметр »-u» задается, если в объекте содержатся символы в кодировке UTF-8. Напомним, что аналогичный параметр есть и у утилиты openssl — »-nameopt utf8».

В пакете NSS есть и утилита для просмотра ASN.1-структыры объекта, аналог утилиты openssl asn1.parse. Это утилита derdump:

$derdump -i <просматриваемый файл> [-o <выходной файл>]


Из самого названия утилиты следует, что она работает с файлами в DER-кодировке. Но это не страшно. В состав пакета входит две утилиты, которые конвертируют файлы из PEM/BASE64-кодировки в DER-кодировку и обратно. Это утилиты atob и btoa.
Например, для конвертации сертификата из PEM-формата в DER-формат, в OpenSSL надо выполнить следующую команду:

$openssl x509 -inform der -in CERT.der -out CERT.pem 


В NSS это будет выглядеть так:

$btoa -in CERT.der -out CERT.pem -w "CERTIFICATE"


Параметр »-w» указывает какой текст включить в начало выходного файла и конец. В данном случае »-w CERTIFICATE» приведет к появлению стандартного для PEM-формата в OpenSSL заголовка и концевика:

-----BEGIN CERTIFICATE-----
<тело сертификата в кодировке BASE64>
-----END CERTIFICATE----- 


И OpenSSL и NSS могут работать с контейнерами pkcs#12. И они оба позволяют не толькл создавать, но и просмотреть содержимое контейнера pkcs12. Но, при использовании утилиты openssl, требуется сначала разобрать контейнер и сохранить сертификаты из контейнера в отдельных файлах. После этого их можно спокойно просмотреть. В NSS просмотр содержимого контейнера можно выполнить за один проход. Для этого используется утилиты pk12util следующего вида:

pk12util -l <файл с контейнером pkcs12> [-W <пароль к контейнеру pkcs12>] [-d <каталог хранилища NSS>] [-h <токен>]


Например:

$pk12util -l cert_RSA.p12 -W 01234567
Certificate(has private key):
    Data:
        Version: 3 (0x2)
        Serial Number: 3 (0x3)
        Signature Algorithm: PKCS #1 SHA-1 With RSA Encryption
        Issuer: "CN=CA-RSA"
        Validity:
            Not Before: Thu May 21 09:50:00 2020
            Not After : Fri May 21 16:17:00 2021
        Subject: "CN=soft.lissi.ru"
        Subject Public Key Info:
            Public Key Algorithm: PKCS #1 RSA Encryption
            RSA Public Key:
                Modulus:
                    a2:f3:e1:63:fd:4f:60:4e:a9:de:56:37:a6:be:54:f3:
                    3d:67:9a:68:9e:f1:47:69:e3:3a:10:b0:2e:88:0c:ef:
                    7c:7f:48:47:6b:c0:75:63:c7:13:23:88:9a:ff:9a:48:
                    30:6a:a0:52:53:6f:4e:e5:84:c0:a1:b0:50:a2:ab:3d:
                    f9:62:2c:d8:30:be:19:1b:c9:f4:b8:20:57:a1:8e:5e:
                    61:8c:a7:50:91:44:61:99:71:40:bb:dc:4c:b7:7c:67:
                    be:a0:71:26:9f:af:dd:69:63:84:7d:93:3f:92:1b:fb:
                    d1:78:d7:95:75:42:8e:14:a8:63:e2:7b:7d:ef:c8:74:
                    35:7c:39:44:82:ad:92:1f:98:0e:91:95:c8:d8:bd:41:
                    fc:44:7e:4d:f5:94:d1:cc:25:ea:df:69:d7:b1:d7:86:
                    ad:4d:03:f1:35:65:03:a6:84:f8:26:6e:9b:d3:c9:67:
                    d5:a5:a4:9e:c7:82:76:28:9f:90:14:f1:16:6a:29:5d:
                    f8:df:c6:6c:e4:21:0d:6f:c5:87:61:a0:65:e3:97:0f:
                    96:42:ad:7d:96:79:ef:1d:ab:6c:e3:a0:da:3a:65:d8:
                    39:69:f3:20:e2:b1:27:fe:cb:4c:8c:0c:f5:76:f2:65:
                    a0:c7:bb:08:b0:f5:50:c0:96:8a:30:e9:75:f7:56:65
                Exponent: 65537 (0x10001)
        Signed Extensions:
            Name: Certificate Basic Constraints
            Critical: True
            Data: Is not a CA.

            Name: Certificate Key Usage
            Usages: Digital Signature
                    Non-Repudiation
                    Key Encipherment

            Name: Certificate Subject Alt Name
            DNS name: "lissi.ru"

            Name: Certificate Type
            Data: 

            Name: Certificate Comment
            Comment: "xca certificate"

    Signature Algorithm: PKCS #1 SHA-1 With RSA Encryption
    Signature:
        12:8c:c3:7e:e9:18:5a:d7:ee:f8:10:8b:72:55:ba:ee:
        8b:85:6c:aa:e3:de:58:26:a2:da:15:c6:3b:15:d9:82:
        6d:02:33:16:cc:0c:84:9d:96:b0:67:d4:63:10:b5:42:
        a1:c3:de:cb:40:6f:9b:9b:eb:c1:98:b6:66:55:ae:88:
        56:14:02:5c:62:8c:bc:22:97:94:cf:53:da:2e:47:c1:
        c6:83:dc:39:6f:0b:b8:39:4e:66:89:a3:9d:51:c6:e3:
        bd:fc:9e:f3:7b:02:a4:77:bc:08:4e:89:e6:57:54:5c:
        c1:cc:83:93:9e:4e:f5:41:4e:b5:13:bc:64:29:a9:8d:
        ce:13:ae:48:6c:21:fc:da:2a:a2:87:67:f8:df:23:53:
        08:a3:11:93:69:91:84:40:4b:58:c1:f3:d0:78:dc:33:
        f6:a5:a6:6f:ed:39:a9:ec:f3:48:e8:06:09:4c:c3:9f:
        9c:0f:58:80:7f:f5:09:40:2a:f1:cf:42:d7:5b:57:62:
        99:e7:dc:a5:31:f3:9d:1f:5a:88:c2:30:1b:8c:ec:69:
        8b:87:dc:4c:08:9e:70:49:3d:5e:7b:8f:6f:98:50:8b:
        0d:b9:8f:c1:7e:9b:1f:c2:76:3a:ca:c5:e3:3d:ea:93:
        81:c0:3b:e2:b7:d1:5d:e4:fd:48:d6:1b:8f:96:e2:18
    Fingerprint (SHA-256):
        D3:38:99:C9:8B:A5:49:96:BC:26:7B:10:1E:2A:7C:4B:55:15:E5:94:47:C6:D0:49:44:2E:48:58:1B:CF:83:7E
    Fingerprint (SHA1):
        D5:26:80:B7:CE:40:5B:54:85:F6:B2:31:58:C3:3E:9D:A4:3D:C1:F3

    Friendly Name: soft.lissi.ru

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1 (0x1)
        Signature Algorithm: PKCS #1 SHA-1 With RSA Encryption
        Issuer: "CN=CA-RSA"
        Validity:
            Not Before: Wed May 20 16:12:00 2020
            Not After : Tue May 21 16:12:00 2030
        Subject: "CN=CA-RSA"
        Subject Public Key Info:
            Public Key Algorithm: PKCS #1 RSA Encryption
            RSA Public Key:
                Modulus:
                    a3:ca:c1:3b:ac:17:1b:32:69:90:8c:70:3b:95:3e:78:
                    4c:90:55:27:2a:25:05:16:54:d3:88:69:b0:43:a0:20:
                    3d:ca:0d:a2:f9:a5:2f:8c:e1:69:b6:df:79:bd:25:7d:
                    aa:71:2b:f2:9f:82:f1:e7:49:cf:fa:3c:b6:6f:80:09:
                    b2:ee:d5:18:e3:3d:96:67:38:cb:9c:e8:e5:76:c4:a8:
                    0b:b9:ad:dd:42:25:c7:da:cf:d4:15:41:bf:b0:0e:4f:
                    d1:9c:b7:d0:b1:32:a0:c7:14:67:ba:a2:9a:e7:23:26:
                    d7:7e:32:d9:5d:15:47:9e:4b:b0:b1:8b:04:38:1e:c3:
                    b2:fc:17:fe:8e:d1:cb:de:de:fd:13:17:b3:0e:5b:58:
                    e1:37:c7:12:32:b6:94:82:77:b8:4c:87:99:c6:c3:7d:
                    51:ed:3c:41:73:31:aa:13:de:26:84:e7:f7:a9:34:e9:
                    b3:9e:7d:aa:91:65:79:a7:14:9d:fc:45:42:de:e6:43:
                    9d:67:96:94:66:38:0b:2e:32:0a:4d:c3:3d:14:b9:06:
                    6b:e0:92:e2:35:0c:8f:78:7f:2c:ad:ec:dc:67:66:0b:
                    8c:47:82:c5:0e:39:a5:35:75:b5:fb:7f:2d:07:97:ef:
                    15:d8:fc:d4:72:6a:da:32:86:9e:64:ea:4a:e3:37:5b
                Exponent: 65537 (0x10001)
        Signed Extensions:
            Name: Certificate Basic Constraints
            Critical: True
            Data: Is a CA with no maximum path length.

            Name: Certificate Key Usage
            Usages: Certificate Signing
                    CRL Signing

            Name: Certificate Type
            Data: 

            Name: Certificate Comment
            Comment: "xca certificate"

    Signature Algorithm: PKCS #1 SHA-1 With RSA Encryption
    Signature:
        24:90:ac:91:3f:13:f6:1a:d4:3c:1b:de:33:e1:4a:0c:
        d8:27:a0:00:d2:43:c8:1b:13:90:93:d3:d2:f0:fe:79:
        da:14:fd:34:2e:3a:f4:fc:c8:71:c9:4f:0d:65:c0:fd:
        40:04:92:ef:7e:72:35:09:4a:08:1e:ed:21:53:06:03:
        73:f9:13:e7:a3:9c:e2:17:9c:25:b2:a5:f9:dc:07:7d:
        32:9f:cd:82:85:6c:26:79:dd:ee:e7:31:4e:10:55:19:
        d6:ac:1e:70:39:01:d2:37:00:3b:41:de:a9:c2:bd:bf:
        b4:c1:f8:8d:bd:d4:6b:95:6d:53:f3:17:76:40:d4:05:
        a4:1e:69:e8:54:92:91:bf:89:b6:ba:45:c5:14:89:bb:
        f4:44:cf:91:ca:16:44:55:86:8f:b9:37:4e:9e:9e:04:
        cd:48:e7:57:ec:c8:e2:72:f3:df:34:49:0a:9b:3f:67:
        a4:01:dd:f3:a3:bb:ec:b5:b8:20:f5:7e:45:8e:ae:53:
        7e:b8:92:38:0a:b7:41:8e:81:15:ab:72:42:f7:37:4a:
        6d:d7:4f:aa:0a:99:ee:9b:49:16:54:03:42:d6:fe:c1:
        ee:63:71:28:b1:84:c2:e6:d4:7b:f6:10:4c:a0:7a:39:
        9d:03:30:ff:78:24:ce:5b:ac:fe:ac:6d:f6:61:77:a6
    Fingerprint (SHA-256):
        AA:1F:B9:29:D2:F9:CC:AB:3D:F7:8C:26:26:4B:51:A3:71:01:1A:94:F8:FE:47:1D:BD:E3:72:DD:63:17:FE:6C
    Fingerprint (SHA1):
        B3:7A:A1:65:01:E2:A0:09:F4:55:17:EC:40:88:5C:42:9A:45:F5:36

Key(shrouded):
    Friendly Name: soft.lissi.ru

    Encryption algorithm: PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC
        Parameters:
            Salt:
                08:0b:8d:be:fa:fc:a5:a3
            Iteration Count: 2048 (0x800)
$


Утилита удобная, но без ложки дегтя не обошлось. Ложка дегтя состоит в том, что русские буквы, вернее, UTF-8 кодировка отображается в виде точек (…). И если у утилиты pp есть параметр -u (присутствует кодировка utf-8), то здесь про нее забыли (мы еще раз сталкнемся с этим при рассмотрении утилиты certutil). Исправить это не составляет труда: достаточно в функцию P12U_ListPKCS12File, находящуюся в файла pk12util.c, добавить одну строку:

PRIntn
P12U_ListPKCS12File(char *in_file, PK11SlotInfo *slot,
                    secuPWData *slotPw, secuPWData *p12FilePw)
{
    SEC_PKCS12DecoderContext *p12dcx = NULL;
    SECItem uniPwitem = { 0 };
    SECStatus rv = SECFailure;
    const SEC_PKCS12DecoderItem *dip;
/*Вызов функции для отображения UTF-8*/
    SECU_EnableUtf8Display(PR_TRUE);

.   .   .   .   .

}


После этого проблем с русскими буквами не будет.
$ pk12util -l 1000.p12 -d ».» -W 01234567
Certificate (has private key):
Data:
Version: 3 (0×2)
Serial Number: 4096 (0×1000)
Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
Issuer: «E=ca@test.ru, OGRN=1111111111111, INN=222222222222, CN=Удос
товеряюший Центр, OU=Отдел Удостоверя
юший Центр, O=Удостоверяюший Центр, STR
EET=«ул. Хавровская, д. 0», L=Хабраград, ST=М
осковская область, C=RU»
Validity:
Not Before: Tue Jul 07 08:40:14 2020
Not After: Fri Aug 06 08:40:14 2021
Subject: «E=test@rsa.ru, CN=Тестовый сертификат»
Subject Public Key Info:
Public Key Algorithm: PKCS #1 RSA Encryption
RSA Public Key:
Modulus:
9a:9f:6c:60:94: f7: ec: f7:94: b3:51:01: e2:1a: c5:25:
28: bb:02:77:49:52:4d:99:8a:6e:26:12:55:8f:71:34:
04: da:39:24: f9: b4:6b: d0:0a:42:27:1b: b2: d7:9b: d9:
c3:76: b0: e0:1c:7c:21: ce:79:9f: d5:2b:17:63: cb:94:
5b: d9: b2:53: ff: b9: bf:4f:3d: cf: b7:8d:8a:37: ba:02:
8c: da: d2:0d: fd:46:5b:45:1d:95:64:07:6e: fa:88:0d:
a4: bd: b3:4a: ed:99: f1: fd:73: c5: b6:05: a0: e5: ee:6b:
c3:83:5b: d0:64:05:77:6a:18: d8: c8:28: a1: d0:06:41:
23:0d: bb:87:8a:77:14: fb:6c:5d: af: db:2b:0b:11: a3:
16:1b:2b:05:18:26: a9: b5:00:4a:40: da: b3:05: aa:2a:
67: c0:18:0d:03: f7: d2: b9: ba:7c:36: f9:95:2e:56:81:
a3:09:99:5e:20:10:95:38:10: c9: c1:6f: c3:6c: a6:1b:
78:51: c6: e4:4f:11: bc: c0:22:4b: ca:59:16: f2:45:95:
0d: fd:7b:46: cf: c7: ac:1c:3d: d7:26: fc: ad:80:3e:2c:
21:93:29:32: a6:79: e2: a8: c6: e9:5e:45:34: d3:38:57:
8f: cd:95:5e:91:09:84:34:21: d2:16:29:69:75:4d: a3
Exponent: 65537 (0×10001)
Signed Extensions:
Name: Certificate Basic Constraints
Critical: True
Data: Is not a CA.

Name: Certificate Key Usage
Usages: Digital Signature
Key Encipherment
Key Agreement

Name: Certificate Type
Data:

Name: Extended Key Usage
TLS Web Client Authentication Certificate
E-Mail Protection Certificate

Name: Certificate Subject Key ID
Data:
26: a1: b3:98:1c: fe:62: ba:23:81:96:37:3f:08: bd:70:
d6: f2: b1:46

Name: Certificate Authority Key Identifier
Key ID:
0a: b6: f6:87:64:1d:8e: b3:63:08:29:9f:21:59: ad:47:
d8: ea:07: f4
Issuer:
Directory Name: «E=ca@test.ru, OGRN=1111111111111, INN=22222222
2222, CN=Удостоверяюший Центр, OU=Отд
ел Удостоверяюший Центр, O=Удост
оверяюший Центр, STREET=«ул. Хавровс
кая, д. 0», L=Хабраград, ST=Московска
я область, C=RU»
Serial Number:
00: a2:9b:22:32:3e: a7:3d: d8

Name: Certificate Subject Alt Name
RFC822 Name: «test@rsa.ru»

Name: Certificate Issuer Alt Name
Error: Parsing extension: Certificate extension value is invalid.
Data: Sequence {
}

Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
Signature:
2f:75:7e:71:9e:15:5c:97: fe: a2: e1:2a:52:39:56:55:
e0:62:60: bc:5f:6d: c2: b6: ec: cd:8b:10: b3: b1:3f: e5:
d6: d1:5f: a5: fa:61: c1: ce:3e: db:6a:2f: b2:13:46:8d:
67: cf:18:09:61:97:01:45: bc:99: bb:0c: d6:0a: a3:03:
87:0a:8e:10:3a: d5: e3:94:6d:4a:24: fa: c3:40:0b:43:
c2:3b:00:56:06: c4: d2: fc: b2:7e: e9:00: e5:2f:4b: e2:
3a:91:49: ce: f8: c3:60: ec:01:74: d8:1a:3b: af: e6: f6:
91: db: c5: f1: d7: de: be:18:38:47:41:8a: e2: ef:80:91:
10:54:41: ae:55:22:6f: d7:8c: fa:46: b6: b6:2a: ee:6a:
0c: c9:03:18: af:4e:93:6c:61: f3: b4:78:0c:61:93: f1:
d8:1b:00: c3: e5:29:9a:08:0a: f8:31:67:88:3d: c3:88:
7a:60: c0: c4:52:94:25:56: e5: a3: df:7d:58: c5: df:9a:
c7:22:7e:2c: f6: fb:2c: bf: b7:7f: c5: ca:2b:0f:8c:20:
77: b9:1f: e0:62:5a:3d: d4:6f:12: ea: c8:51:67: a5:75:
ad: e9: ac:9e:4e:2e:2d:34:80: e7: d8:64: f6:8f:2f:33:
32:1f:8b: bc:9c: e8:77:4a: ee:7b:84:31: ec:28: e9:70
Fingerprint (SHA-256):
96: F4: A5: FA:6D:8A: F8:7E: A6:10:49: BD:43:34: C1:92: C6:7D: FF:63:41:8E:69: C0: AC:34:6B: CB:63:7B:56:31
Fingerprint (SHA1):
B6:91:9B: C6:7A:45:9C:92: FD: E7: C7:33:00: FA:91: DF:7D:5F:00:21

Friendly Name: Тестовый сертификат

Certificate:
Data:
Version: 3 (0×2)
Serial Number:
00: a2:9b:22:32:3e: a7:3d: d8
Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
Issuer: «E=ca@test.ru, OGRN=1111111111111, INN=222222222222, CN=Удос
товеряюший Центр, OU=Отдел Удостоверя
юший Центр, O=Удостоверяюший Центр, STR
EET=«ул. Хавровская, д. 0», L=Хабраград, ST=М
осковская область, C=RU»
Validity:
Not Before: Tue Jul 07 08:08:11 2020
Not After: Fri Jul 05 08:08:11 2030
Subject: «E=ca@test.ru, OGRN=1111111111111, INN=222222222222, CN=Удос
товеряюший Центр, OU=Отдел Удостоверя
юший Центр, O=Удостоверяюший Центр, STR
EET=«ул. Хавровская, д. 0», L=Хабраград, ST=М
осковская область, C=RU»
Subject Public Key Info:
Public Key Algorithm: PKCS #1 RSA Encryption
RSA Public Key:
Modulus:
e7:08: ed:83:08:10:7b:48:56:37:8b: e2:4a:31:1a:7b:
0d:4e: d2: a2:67: d7:04:60: a0:09: db:06:64:21:01:4e:
0d:41: d8:61:15: c6:58:83:66:7e:6b:65:72:0d:2b: c3:
50:26:11:04:82:4b:1a:12: d0: dc: e1:13:1c:76:69:0f:
c2:59: e2:5d:60:6d: fe:8a:48: fa:8b:1e:05:07:34:6d:
8a: e3:76:23:42:9e:7b:64:0b:6a: fb:36:63:31:96: df:
ed: d3: e8:7c:6e:39: d4:7d: da: b8: f4: ec:53:57:60: f1:
d8: a4:3a:3f:3b:4a:63:6c:2a:55:90:21:15:23:4a:37:
21:31: a0: c4: bb:84:0d:96:18:3c:3b: ba:92: e3: e2:17:
56: e5: d9:8c:58:24:8a: a3:53: b6:4f:02:4d:30: a6:0f:
34: ad:20: cf:6f:03: ca:23:1e: d3:15: bc:80:09: d8:1e:
90:07: da:90: a9:34:9e:6e: ed:6b:10: b7: a1: a4: a9: b4:
04: ac:6a:40: d8:00:52: d6:6a:28: f2:8c: c6:84:81:8a:
cd:63: a6:53:82: d2:4e:11: ec:94:81: d7:9c:79:8a:30:
9c:40:75:4d: d9:88:0b: cc: a4:0c:5d:6d:23: a6: ac:56:
8c:49: d9:1f:2b:63: cb:50: fc: a3: e0:3e:35:4e: f4:03
Exponent: 65537 (0×10001)
Signed Extensions:
Name: Certificate Basic Constraints
Critical: True
Data: Is a CA with no maximum path length.

Name: Certificate Subject Key ID
Data:
0a: b6: f6:87:64:1d:8e: b3:63:08:29:9f:21:59: ad:47:
d8: ea:07: f4

Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
Signature:
17:7d:29: dc:4d:6e:4c:99:7a: bc: b2:2a: a5:80: f9:5f:
0c:60:00:2b: f3: f4: ef:19: d7: ed:56:07:5d:24: e1: b3:
f6:43: e2:05:9b:75: ce: cd: cf:27:1e:1c: cd: d8: cc:43:
77:16:04:7e:8a: dd:89: c4: b2:75: ae: f4:84:23:53:18:
fe: be: c5:1d:40:55: aa:91:9f: f5:96:06:5d:07:22: a8:
1c: b9:29: c4:49:2e:75:10:75:22:95:36:16:58:2f:77:
f5: fa:6d: de: c4:67: ca: f3: e1:98:51: b4: ba: b7:2a:7f:
06: db:33:5a: a6: bb:53:57: f4:18:93:16:9c:0e:43: d0:
46: e6:84:55: bb: ff:68: fe: fa:32: d5:23:2a: d5:65:9b:
d9:63:45:6b:53:71:64: dd: da: e1:40: fa:89:30: b1:73:
8b: f8:7c:3c:2f:72:24: ad: e8:5c:07:89:2f:3a:0d:37:
48:29:1f:0d:5f:9e:11:73:56: b8: d9:24: eb:2d:2e:18:
c7:9b:90:62:09:20:61:75: b9: a1:9a:3f:99:34:8e:06:
30: ce:7d:60:42:7d: e0:14: f2:88: f2:41: a0:46:4d:55:
17: d4: c2:15:64: c9:3e: f5: cc:0a:41: f7: c0: d0:94:96:
ea:64: e0:45:3a: e0: a3: d6:22: a9: d1: e3: c4:51: e8:96
Fingerprint (SHA-256):
F5: DF:15:79:5E:1E:41:84:96:8C:8C: CA:37:0C: A6: BB: C3:21: AE:3D:32:42:8C:63: C2:64: BA:0A:74: DC:37: F8
Fingerprint (SHA1):
CF: C6: B9: D4:3C:16:6F:31:91:2A:09:2F: FE:4C:57:89:0F:5A: F1: DB

Friendly Name: Удостоверяюший Центр

Key (shrouded):
Friendly Name: Тестовый сертификат

Encryption algorithm: PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC
Parameters:
Salt:
c4: fa:4a:6a:4f:54: a1:7a
Iteration Count: 2048 (0×800)
$


Говоря о создании контейнера PKCS#12 утилитой openssl, то мы воспользовались графической оболочной CAFL63:

1-s8spd_pddxjeup14nvzcj2eie.png

Теперь самое время поговорить о хранилище NSS.

Хранилище NSS


Хранилищем NSS является каталог, в котором хранится три базы данных.
В базе данных (БД) cert8.db/cert9.db хранятся сертификаты. В БД key3.db/key4.db хранятся закрытые ключи. И, наконец, в БД secmod.db/pkcs11.txt хранится информация (прежде всего путь к библиотеки), позволяющая работать со сторонними токенами/смарткартами/облаками с интерфейсом PKCS#11.
Для создания хранилища NSS предназначена утилита modutil следующего формата:

modutil -create -force [-dbdir <хранилище NSS>] , где
<хранилище NSS> := [<тип базы данных>:]<каталог хранилища NSS>
<тип базы данных> := dbm|sql , например:
$modutil -create -force -dbdir "sql:/~/TEST_NSS"


Тип базы данных dbm предполагает создание баз данных Berkeley (cert8.db, key3.db и secmod.db). Тип sql предполагает создание баз данных SQLite3 (cert9.db, key9.db и текстовый файл pkcs11.txt). По умолчанию создаются базы данных SQLite3. Каталог хранилища NSS должен быть создан заранее. По умолчанию (если не задан параметр -dbdir или -d) используется хранилище ».netscape» в домашней папке пользователя. Именно это хранилище использует, например, броузер google-chrome.
Также просто из хранилища сертификатов старого формата (DBM) (cert8.db, key3.db и secmod.db) создается и хранилище в новом формате (SQLite3) (cert9.db, key4.db и pkcs11.txt). Для этого достаточно выполнить утилиту работы с сертификатами certutil в режиме просмотра ключей (-K) или сертификатов (-L) с параметром –X, например:

$certutil -K -X -d ~/TEST_NSS


или 

$certutil -L -X -d ~/TEST_NSS


Отметим, что такие хранилища есть во всех проектах, построенных на NSS, включая Firefox, Thunderbird, Seamonkey, GoogleChrome, LibreOffice.
После создания хранилиша NSS автоматически становится доступным встроенный модуль «NSS Internal PKCS #11 Module» с двумя встроенными токенами:

$modutil -list -dbdir ~/TEST_NSS
Listing of PKCS #11 Modules
-----------------------------------------------------------
  1. NSS Internal PKCS #11 Module
           uri: pkcs11:library-manufacturer=Mozilla%20Foundation;library-description=NSS%20Internal%20Crypto%20Services;library-version=3.52
         slots: 2 slots attached
        status: loaded

         slot: NSS Internal Cryptographic Services
        token: NSS Generic Crypto Services
          uri: pkcs11:token=NSS%20Generic%20Crypto%20Services;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203

         slot: NSS User Private Key and Certificate Services
        token: NSS Certificate DB
          uri: pkcs11:token=NSS%20Certificate%20DB;manufacturer=Mozilla%20Foundation;serial=0000000000000000;model=NSS%203
-----------------------------------------------------------
$


Токен NSS Generic Crypto Services реализует криптографические функции и механизмы, а токен «NSS Certificate DB» предназначен для хранения сертификатов и ключей и другой дополнительной информации (например, о доверии корневым сертификатам). Токен «NSS Certificate DB» (внутренний токен NSS) для хранения сертификатов использует базу данных cert8.db/cert9.db, а закрытые ключи хранит в базе данных key3.db/key4.db.
Получить информацию о встроенных токенах внутреннего модуля «NSS Internal PKCS #11 Module», включая поддерживаемые по умолчанию криптографические механизмы, можно путем выполнения следующей команды:

$modutil -list 'NSS Internal PKCS #11 Module' -dbdir ~/TEST_NSS
 — Name: NSS Internal PKCS #11 Module
Library file: **Internal ONLY module**
Manufacturer: Mozilla Foundation
Description: NSS Internal Crypto Services
PKCS #11 Version 3.0
Library Version: 3.52
Cipher Enable Flags: None
Default Mechanism Flags: RSA: ECC: DH: RC2: RC4: DES: AES: CAMELLIA: SEED: SHA1: SHA256: SHA512: MD5: MD2: SSL: TLS

Slot: NSS Internal Cryptographic Services
Slot Mechanism Flags: RSA: ECC: DH: RC2: RC4: DES: AES: CAMELLIA: SEED: SHA1: SHA256: SHA512: MD5: MD2: SSL: TLS
Manufacturer: Mozilla Foundation
Type: Software
Version Number: 3.52
Firmware Version: 1.0
Status: Enabled
Token Name: NSS Generic Crypto Services
Token Manufacturer: Mozilla Foundation
Token Model: NSS 3
Token Serial Number: 0000000000000000
Token Version: 4.0
Token Firmware Version: 0.0
Access: Write Protected
Login Type: Public (no login required)
User Pin: NOT Initialized

Slot: NSS User Private Key and Certificate Services
Slot Mechanism Flags: None
Manufacturer: Mozilla Foundation
Type: Software
Version Number: 3.52
Firmware Version: 1.0
Status: Enabled
Token Name: NSS Certificate DB
Token Manufacturer: Mozilla Foundation
Token Model: NSS 3
Token Serial Number: 0000000000000000
Token Version: 0.0
Token Firmware Version: 0.0
Access: NOT Write Protected
Login Type: Public (no login required)
User Pin: Initialized
— $


Подключение дополнительного модуля для работы с внешними устройствами PKCS#11 делается все той же утилитой modutil:

$modutil -add <имя модуля> -libfile <путь к библиотеке> [-dbdir <хранилище NSS>]


Например, для работы с токенами РУТокен, поддерживающими российскую криптографии, достаточно выполнить следующую команду:

$modutil -add "ruTokenECP" -libfile /usr/lib64/librtpkcs11ecp_2.0.so -dbdir $HOME/.netscape 


Для получения списка модулей, которые поддерживает то или иное хранилище NSS, с информацией о каждом модуле (библиотека, список поддерживаемых слотов и подключенных к ним товенах) необходимо выполнить следующую команду:

$modutil -list [-dbdir <хранилище NSS>]


Для получения полной информации о подключенных токенах для конкретного модуля необходимо будет выполнить следующую команду:

$modutil -list <имя модуля> [-dbdir <хранилище NSS>]


Мы ее уже прльзовались, когда получали информацию о встроенных (внутренних) токенах NSS.
И, если можно добавить модуль, то можно и удалить модуль из базы данных:

$modutil -delete <имя модуля> [-dbdir <хранилище NSS>] 


Доступ к внешним токенам, как правило, защищен PIN-кодом. А вот доступ к встроенному токену «NSS Certificate DB» по умолчанию не защищен паролем (PIN-кодом). Но установить не составляет труда, например:

$modutil -dbdir $HOME/.netscape -changepw "NSS Certificate DB"  


Аналогичным образом можно поменять PIN-код и у внешнего токена.
Теперь самое время перейти к работе с токенами, его мехамизмами и объектами.

Доступ к объектам токена PKCS#11


Для доступа к объектам (ключи, сертификаты) токенов PKCS#11 служит утилита certutil. Отметим, что своей функциональности утилита certutil не уступает утилите openssl. Для просмотра функциональности утилиты certutil достаточно выполнить команду:

$certutil -H


Но нас сейчас интересует только доступ с сертификатам и ключам. Напомним, что при хранении на токене PKCS#11 и тем и другим, как правило, приписываются атрибуты CKA_ID и CKA_LABEL. Для просмотра списка сертификатов на том или ином токене необходимо выполнить следующую команду:

$certutil -L [-d <хранилище NSS>] [-h <метка токена>]


В качестве метки токена может быть указана реальная метка токена, или одно из ключевых слов — all или internal. В первом случае (метка токена all) перебираются все токены, подключенные к хранилищу NSS, а во втором случае (internal или «NSS Certificate DB») будет просматриваться внутренний токен хранилища «NSS Certificate DB».
Например, для получения списка сертификатов, находящихся на токене с меткой «LS11SW2016», модуль доступа к которому зареегистрирован в хранилище NSS »/home/a513/tmp/TEST_NSS» необходимо выполнить следующую команду:

$ certutil -L -d /home/a513/tmp/TEST_NSS -h "LS11SW2016"
Enter Password or Pin for "LS11SW2016":
Certificate Nickname                                  Trust Attributes
                                                      SSL,S/MIME,JAR/XPI
LS11SW2016:TestCA_P11                                 u,u,u
LS11SW2016:clientnss from CryptoArmPKCS               u,u,u
LS11SW2016:ТестШифр                                   u,u,u
LS11SW2016:Thenderbird-60.3.0 from 32                 u,u,u
LS11SW2016:Всесильный Хабр from УЦ 12_512             u,u,u
LS11SW2016:Text4Key                                   u,u,u
LS11SW2016:KmailKleopatra от GnuPG-2001               u,u,u
LS11SW2016:setvernss from CryptoArmPKCS               u,u,u
LS11SW2016:Ф И О from УЦ 12_512                       u,u,u
LS11SW2016:Test 12 512                                u,u,u
LS11SW2016:Kleopatra от GnuPG-2001                    ,,   
$


Список сертификатов, находящихся на токене, выводится в две колонки. В первой колонке дается nicknamе сертификата, а во второй — атрибуты доверия этого сертификата.
При чем, если сертификат имеет закрытый ключ на токене, где он находится, то в этой колонке
будет значение «u, u, u».
Если атрибуты не устанавливались, то в колонке будет значение »,,».
Сертификаты с аттрибутами доверия «u, u, u» (у них есть закрытый ключ) могут быть использованы для аутентификации или формирования электронной подписи.
Другие значения атрибутов доверия могут быть установлены для сертификатов, находящихся на встроенном токене. «NSS Certificate DB». Но об этом позже.
Что же такое nickname сертификата в NSS?

 := [<метка токена>:]


Для внутреннего токена («NSS Certificate DB») метка токена в nickname может отсутствовать.
Если рассматривать мехамизмы токенов PKCS#11, то мы увидим, что операции генерации ключей, импорта сертификатов и ключей сами по себе не предусматривают установку значений аттрибутов CKA_ID и CKA_LABEL. Это все перекладывается на разработчика прикладного ПО. Но, если вы используете, утилиты NSS для работы с токенами, то оказывается, что они берут на себя эти хлопоты.
Для просмотра списка закрытых ключей используется следующая команда:

$certutil -K [-d <хранилиже NSS>] [-h <метка токена>]


При этом распечатывается тип ключа, CKA_ID и CKA_LABEL ключа.
Но вернемся к сертификатам. Для просмотра сертификата, находящегося на токене, в текстовом виде достаточно выполнить команду:

$certutil -L [-d <хранилище NSS>] -n 


Например:

certutil -L -d '/home/a513/tmp/TEST_NSS' -n 'NSS Certificate DB: Тестовый сертификат'
$ certutil -L -d »/home/a513/tmp/TEST_NSS» -n «NSS Certificate DB: Тестовый сертификат»
Certificate:
Data:
Version: 3 (0×2)
Serial Number: 4096 (0×1000)
Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
Issuer: «E=ca@test.ru, OGRN=1111111111111, INN=222222222222, CN=Удос
товеряюший Центр, OU=Отдел Удостоверя
юший Центр, O=Удостоверяюший Центр, STR
EET=«ул. Хавровская, д. 0», L=Хабраград, ST=М
осковская область, C=RU»
Validity:
Not Before: Tue Jul 07 08:40:14 2020
Not After: Fri Aug 06 08:40:14 2021
Subject: «E=test@rsa.ru, CN=Тестовый сертификат»
Subject Public Key Info:
Public Key Algorithm: PKCS #1 RSA Encryption
RSA Public Key:
Modulus:
9a:9f:6c:60:94: f7: ec: f7:94: b3:51:01: e2:1a: c5:25:
28: bb:02:77:49:52:4d:99:8a:6e:26:12:55:8f:71:34:
04: da:39:24: f9: b4:6b: d0:0a:42:27:1b: b2: d7:9b: d9:
c3:76: b0: e0:1c:7c:21: ce:79:9f: d5:2b:17:63: cb:94:
5b: d9: b2:53: ff: b9: bf:4f:3d: cf: b7:8d:8a:37: ba:02:
8c: da: d2:0d: fd:46:5b:45:1d:95:64:07:6e: fa:88:0d:
a4: bd: b3:4a: ed:99: f1: fd:73: c5: b6:05: a0: e5: ee:6b:
c3:83:5b: d0:64:05:77:6a:18: d8: c8:28: a1: d0:06:41:
23:0d: bb:87:8a:77:14: fb:6c:5d: af: db:2b:0b:11: a3:
16:1b:2b:05:18:26: a9: b5:00:4a:40: da: b3:05: aa:2a:
67: c0:18:0d:03: f7: d2: b9: ba:7c:36: f9:95:2e:56:81:
a3:09:99:5e:20:10:95:38:10: c9: c1:6f: c3:6c: a6:1b:
78:51: c6: e4:4f:11: bc: c0:22:4b: ca:59:16: f2:45:95:
0d: fd:7b:46: cf: c7: ac:1c:3d: d7:26: fc: ad:80:3e:2c:
21:93:29:32: a6:79: e2: a8: c6: e9:5e:45:34: d3:38:57:
8f: cd:95:5e:91:09:84:34:21: d2:16:29:69:75:4d: a3
Exponent: 65537 (0×10001)
Signed Extensions:
Name: Certificate Basic Constraints
Critical: True
Data: Is not a CA.

Name: Certificate Key Usage
Usages: Digital Signature
Key Encipherment
Key Agreement

Name: Certificate Type
Data:

Name: Extended Key Usage
TLS Web Client Authentication Certificate
E-Mail Protection Certificate

Name: Certificate Subject Key ID
Data:
26: a1: b3:98:1c: fe:62: ba:23:81:96:37:3f:08: bd:70:
d6: f2: b1:46

Name: Certificate Authority Key Identifier
Key ID:
0a: b6: f6:87:64:1d:8e: b3:63:08:29:9f:21:59: ad:47:
d8: ea:07: f4
Issuer:
Directory Name: «E=ca@test.ru, OGRN=1111111111111, INN=22222222
2222, CN=Удостоверяюший Центр, OU=Отд
ел Удостоверяюший Центр, O=Удост
оверяюший Центр, STREET=«ул. Хавровс
кая, д. 0», L=Хабраград, ST=Московска
я область, C=RU»
Serial Number:
00: a2:9b:22:32:3e: a7:3d: d8

Name: Certificate Subject Alt Name
RFC822 Name: «test@rsa.ru»

Name: Certificate Issuer Alt Name
Error: Parsing extension: Certificate extension value is invalid.
Data: Sequence {
}

Signature Algorithm: PKCS #1 SHA-256 With RSA Encryption
Signature:
2f:75:7e:71:9e:15:5c:97: fe: a2: e1:2a:52:39:56:55:
e0:62:60: bc:5f:6d: c2: b6: ec: cd:8b:10: b3: b1:3f: e5:
d6: d1:5f: a5: fa:61: c1: ce:3e: db:6a:2f: b2:13:46:8d:
67: cf:18:09:61:97:01:45: bc:99: bb:0c: d6:0a: a3:03:
87:0a:8e:10:3a: d5: e3:94:6d:4a:24: fa: c3:40:0b:43:
c2:3b:00:56:06: c4: d2: fc: b2:7e: e9:00: e5:2f:4b: e2:
3a:91:49: ce: f8: c3:60: ec:01:74: d8:1a:3b: af: e6: f6:
91: db: c5: f1: d7: de: be:18:38:47:41:8a: e2: ef:80:91:
10:54:41: ae:55:22:6f: d7:8c: fa:46: b6: b6:2a: ee:6a:
0c: c9:03:18: af:4e:93:6c:61: f3: b4:78:0c:61:93: f1:
d8:1b:00: c3: e5:29:9a:08:0a: f8:31:67:88:3d: c3:88:
7a:60: c0: c4:52:94:25:56: e5: a3: df:7d:58: c5: df:9a:
c7:22:7e:2c: f6: fb:2c: bf: b7:7f: c5: ca:2b:0f:8c:20:
77: b9:1f: e0:62:5a:3d: d4:6f:12: ea: c8:51:67: a5:75:
ad: e9: ac:9e:4e:2e:2d:34:80: e7: d8:64: f6:8f:2f:33:
32:1f:8b: bc:9c: e8:77:4a: ee:7b:84:31: ec:28: e9:70
Fingerprint (SHA-256):
96: F4: A5: FA:6D:8A: F8:7E: A6:10:49: BD:43:34: C1:92: C6:7D: FF:63:41:8E:69: C0: AC:34:6B: CB:63:7B:56:31
Fingerprint (SHA1):
B6:91:9B: C6:7A:45:9C:92: FD: E7: C7:33:00: FA:91: DF:7D:5F:00:21

Mozilla-CA-Policy: false (attribute missing)
Certificate Trust Flags:
SSL Flags:
User
Email Flags:
User
Object Signing Flags:
User
$


Если у просматриваемого сертификата на этом же токене имеется закрытый ключ, то флаги доверия сертификата (Certificate Trust Flags) будут иметь значение User:

Certificate Trust Flags:
SSL Flags:
User
Email Flags:
User
Object Signing Flags:
User


Для экспорта сертификата с токена в стандартный вывод достаточно добавить дополнительный параметр »-a» или »-r». Параметр »-a» предписывает выводить сертификат в формате PEM:

$certutil -L -d '/home/a513/tmp/TEST_NSS' -n 'NSS Certificate DB: Тестовый сертификат' -a

-----BEGIN CERTIFICATE-----
MIIGiTCCBXGgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwggF2MQswCQYDVQQGEwJS
VTEsMCoGA1UECAwj0JzQvtGB0LrQvtCy0YHQutCw0Y8g0L7QsdC70LDRgdGC0Ywx
GzAZBgNVBAcMEtCl0LDQsdGA0LDQs9GA0LDQtDEqMCgGA1UECQwh0YPQuy4g0KXQ
sNCy0YDQvtCy0YHQutCw0Y8sINC0LiAwMTAwLgYDVQQKDCfQo9C00L7RgdGC0L7Q
stC10YDRj9GO0YjQuNC5INCm0LXQvdGC0YAxOzA5BgNVBAsMMtCe0YLQtNC10Lsg
0KPQtNC+0YHRgtC+0LLQtdGA0Y/RjtGI0LjQuSDQptC10L3RgtGAMTAwLgYDVQQD
DCfQo9C00L7RgdGC0L7QstC10YDRj9GO0YjQuNC5INCm0LXQvdGC0YAxGjAYBggq
hQMDgQMBARIMMjIyMjIyMjIyMjIyMRgwFgYFKoUDZAESDTExMTExMTExMTExMTEx
GTAXBgkqhkiG9w0BCQEWCmNhQHRlc3QucnUwHhcNMjAwNzA3MDg0MDE0WhcNMjEw
ODA2MDg0MDE0WjBMMS4wLAYDVQQDDCXQotC10YHRgtC+0LLRi9C5INGB0LXRgNGC
0LjRhNC40LrQsNGCMRowGAYJKoZIhvcNAQkBFgt0ZXN0QHJzYS5ydTCCASIwDQYJ
KoZIhvcNAQEBBQADggEPADCCAQoCggEBAJqfbGCU9+z3lLNRAeIaxSUouwJ3SVJN
mYpuJhJVj3E0BNo5JPm0a9AKQicbsteb2cN2sOAcfCHOeZ/VKxdjy5Rb2bJT/7m/
Tz3Pt42KN7oCjNrSDf1GW0UdlWQHbvqIDaS9s0rtmfH9c8W2BaDl7mvDg1vQZAV3
ahjYyCih0AZBIw27h4p3FPtsXa/bKwsRoxYbKwUYJqm1AEpA2rMFqipnwBgNA/fS
ubp8NvmVLlaBowmZXiAQlTgQycFvw2ymG3hRxuRPEbzAIkvKWRbyRZUN/XtGz8es
HD3XJvytgD4sIZMpMqZ54qjG6V5FNNM4V4/NlV6RCYQ0IdIWKWl1TaMCAwEAAaOC
AkcwggJDMAwGA1UdEwEB/wQCMAAwCwYDVR0PBAQDAgOoMBEGCWCGSAGG+EIBAQQE
AwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwHQYDVR0OBBYEFCah
s5gc/mK6I4GWNz8IvXDW8rFGMIIBsAYDVR0jBIIBpzCCAaOAFAq29odkHY6zYwgp
nyFZrUfY6gf0oYIBfqSCAXowggF2MQswCQYDVQQGEwJSVTEsMCoGA1UECAwj0JzQ
vtGB0LrQvtCy0YHQutCw0Y8g0L7QsdC70LDRgdGC0YwxGzAZBgNVBAcMEtCl0LDQ
sdGA0LDQs9GA0LDQtDEqMCgGA1UECQwh0YPQuy4g0KXQsNCy0YDQvtCy0YHQutCw
0Y8sINC0LiAwMTAwLgYDVQQKDCfQo9C00L7RgdGC0L7QstC10YDRj9GO0YjQuNC5
INCm0LXQvdGC0YAxOzA5BgNVBAsMMtCe0YLQtNC10Lsg0KPQtNC+0YHRgtC+0LLQ
tdGA0Y/RjtGI0LjQuSDQptC10L3RgtGAMTAwLgYDVQQDDCfQo9C00L7RgdGC0L7Q
stC10YDRj9GO0YjQuNC5INCm0LXQvdGC0YAxGjAYBggqhQMDgQMBARIMMjIyMjIy
MjIyMjIyMRgwFgYFKoUDZAESDTExMTExMTExMTExMTExGTAXBgkqhkiG9w0BCQEW
CmNhQHRlc3QucnWCCQCimyIyPqc92DAWBgNVHREEDzANgQt0ZXN0QHJzYS5ydTAJ
BgNVHRIEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAvdX5xnhVcl/6i4SpSOVZV4GJg
vF9twrbszYsQs7E/5dbRX6×6YcHOPttqL7ITRo1nzxgJYZcBRbyZuwzWCqMDhwqO
EDrV45RtSiT6w0ALQ8I7AFYGxNL8sn7pAOUvS+I6kUnO+MNg7AF02Bo7r+b2kdvF
8dfevhg4R0GK4u+AkRBUQa5VIm/XjPpGtrYq7moMyQMYr06TbGHztHgMYZPx2BsA
w+UpmggK+DFniD3DiHpgwMRSlCVW5aPffVjF35rHIn4s9vssv7d/xcorD4wgd7kf
4GJaPdRvEurIUWelda3prJ5OLi00gOfYZPaPLzMyH4u8nOh3Su57hDHsKOlw
-----END CERTIFICATE-----


Для вывода в DER-формате используется параметр »-r».

Установить сертификат на токен


Предположим у вас есть контейнер PKCS#12 с личным сертификатом и закрытым ключои, который вы сформировали средствами OpenSSL. Для экспорта личного сертификата в хранилище NSS используется команда pk12util следующего вида:

$pk12util -i <контейнер pkcs12> [-d <хранилище NSS>] [-h <метка токена>]


Если вы хотите импортировать сертификат на конкретный токен, то необходимо задать его метку. Отметим еще одну особенность. Если контейнер содержит в своем составе корневые сертификаты, то они будут сохранены на внутреннем токене «NSS Certificate DB». При этом атрибуты доверия по умолчанию не устанавливаются. Если по каким либо причинам требуется установка атрибутов доверия к тем или иным сертификатам центров регистрации (корневым сертификатам) или SSL-сертификатам Для установки аттрибутов доверия используется утилита certutil следующего вида:

$certutil -M -n  -t <аттрибуты доверия> [-d <хранилище NSS>]


Для каждого сертификата есть три доступные категории доверия, выраженные в следующем порядке: SSL, S/MIME, подпись кода для каждого параметра доверия:

<аттрибуты доверия> := x,y,z , где


  • x — аттрибуты для SSL,
  • y — атрибуты для S/MIME,
  • z — атрибуты для подписи кода.


Каждая позиция x, y и z может быть пустой (используйте, без явного доверия) или содержать один или несколько атрибутов:

  • p — Действительный узел (Valid peer);
  • P — доверенный узел (подразумевается и p)
  • c — Действительный сертификат центра регистриции (Valid CA)
  • T — доверенный CA для выдачи клиентских сертификатов (подразумевается и c)
  • C — Доверенный CA для выдачи сертификатов сервера (только SSL) (подразумевается c)


Отметим, что не все внешние токены допускают операцию импорта закрытого ключа на токен.
Для установки просто сертификата из файла используется утилита certutil следующего вида:

$certutil -A -n <метка сертификата> -t <аттрибуты доверия> [-d <хранилище NSS>] [-h <метка токена>] [-a] [-i <файл с сертификатом>]


К сожалению, в данном контексте не эквивалентна nickname сертификата, рассмотренному выше. Здесь метка сертификата соответствует просто CKA_LABEL, просто метки без указания метки токена. Какой-то разнобой.
По умолчанию предполагается, что сертификат находится в файле в DER-кодировке. Если сертификат в PEM-кодировке, то необходимо задавать параметр »-a». Параметр »-i» не задан, то сертификат будет браться из стандартного ввода (stdin). По умолчанию сертификаты устанавливаются в токен «NSS Certificate DB», но можно установить сертификат и на внешний токен (параметр »-h»). При установке сертификата на внешний токен, сертификат будет установлен как на внутренний токен («NSS Certificate DB»), так и внешний токен. При этом аттрибуты довермя для внешнего токена будут проигнорированы, будет выдано предупреждение: «could not change trust on certificate».
Дубликат сертификата на внутреннем токене при желании можно удалить.
Для удаления сертификата с любого токена используется следующая команда:

$certutil -D [-d <хранилище NSS>] -n 


Например, для удаления с токена RuTokenECP20 сертификата с меткой (CKA_LABEL) «Пользователь1» достаточно выполнить следующую команду:

$certutil -D -d /home/a513/tmp/TEST_NSS -n "RuTokenECP20:Пользователь1"


При удалении сертификата его закрытый ключ не удаляется (если он есть, конечно). Для удаления закрытого ключа надо выполнить команду вида:

$certutil -F [-k <тип ключа>] [-d <хранилище NSS>] -n , где
<тип ключа> := rsa|dsa|ec


Теперь, когда у нас имеется хранилище NSS, токены с личными сертификатами, можно поработать и с электронной подписью.

Формирование и проверка электронной подписи


Для работы с электронной подписью в пакете NSS есть три утилиты.
Для формирования электронной подписи используется утилита p7sign:

$pksign -k  [-d <хранилище NSS>] [-e] [-i <подписываемый файл >] [-o <файл для электронной подписи>], где
 := [<метка токена>:]


К сожалению, утилита формирует подпись без привязки ко времени ее формирования. Но это легко исправляется. Достаточно в функцию SignFile в утилите p7sign.c добавть струку с 

© Habrahabr.ru