Użycie podpisu elektronicznego pod Linuksem

W podobnym tonie jak w poprzednim wpisie umieszczę tutaj kilka spostrzeżeń na temat użycia podpisu elektronicznego w systemie Linux.

Podpis elektroniczny a karta kryptograficzna

Z przepisów prawa wynika, że materiał kryptograficzny konieczny do złożenia podpisu elektronicznego musi znajdować się na komponencie technicznym. W praktyce oznacza to, że klucz prywatny do podpisu elektronicznego musi znajdować się na karcie kryptograficznej (lub HSM), z którego nie może on zostać wyciągnięty (w rozwiązaniu SimplySign taka karta/HSM jest przechowywana w serwerowni u operatora usługi).

PKCS#11

PKCS#11 to API udostępniające funkcje potrzebne do implementacji kryptografii z wykorzystaniem kluczy przechowowanych w sprzęcie oraz akceleratorów kryptografii. Nie jest to jedyne API do realizacji tej funkcji w Java bywa używane JCE (providery JCE są dostępne dla HSMów nCipher oraz Gemalto), Microsoft również ma własne API dostępu do kart kryptograficznych wbudowane w Windows (sterowniki dla tego API są instalowane przy instalacji oprogramowania do podpisu).

PKCS#11 zostało opracowane w latach 90tych, dla języka C. Jest to API niezależne od platformy, obecnie istnieją wrappery pozwalające na wywoływanie tego API w różnych językach programowania.

Producenci kart kryptograficznych dostarczają bibliotekę, która implementuje API PKCS#11 i komunikuje się z kartą kryptograficzną aby użyć materiału kryptograficznego przechowywanego na karcie.

Dostępne biblioteki

Biblioteki PKCS#11 są specyficzne dla modelu karty kryptograficznej.

Na dzień 3 grudnia 2019 dostępność bibliotek przedstawia się następująco:

Wystawca Karta Biblioteka
Certum crypotCertum 3.x cryptoCertum3PKCS-2.0.0.43.r2-MS.so
Certum SimplySign SimplySignPKCS_64-MS-1.0.20.so
KIR/Sigillum CC Carbon libccpkip11-2.01.00161.so
CenCert IAS-ECC libencardp11-4.1.1.9.so
  1. Certum udostępnia bibloteki na swojej stronie.
  2. Biblioteki dla kart Carbon, można pobrać ze strony ich producenta firmy CryptoTech.
  3. CenCert udostępnia program PEM-HEART na swojej stronie w nim jest biblioteka PKCS#11.

Ze swojej strony mogę napisać, że testowałem podpisywanie kartami Certum, KIR Carbon i CenCert w systemie Linux i nie miałem problemów. Osobiście nie testowałem podpisu SimplySign (z kartą „w chmurze”).

Niedostępne biblioteki

NIE znalazłem bibliotek PKCS#11 dla systemu Linux do następujących kart:

  • KIR Graphite
  • Sigillum Dark, jest to dziwne, bo pod Windows karta korzysta ze sterowników Athena NXP IDProtect Client, a Athena-SCS chwali się w zakładce „Products”, że IDProtect Client ma Windows, Mac OSX and LINUX support.
  • EuroCert, to też jest dziwne, bo pod Windows i MacOS karty EuroCert korzystają ze sterowników CSSI firmy Charismathics, która chwali się, że ich middleware jest Fully Windows Compliant plus support for Mac, Linux, Embedded and Mobile platforms.

Sprawdzenie czy karta działa

Do sprawdzenia wykorzystuję polecenie pkcs11-tool dla ClearLinux wymaga ono skompilowanie ze źródeł programu OpenSC, a w Ubuntu i RHEL jest dostępne w pakiecie opensc.

Po skonfigurowaniu podpisywania na stronie https://test.giif.mofnet.gov.pl biblioteki zostały pobrane do katalogu /tmp.

CenCert

Sprawdzam czy pkcs11-tool rozpoznaje bibliotekę.

1
2
3
4
5
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libencardp11-4.1.1.9.so -I
Cryptoki version 2.11
Manufacturer ENIGMA SOI Sp. z o.o.
Library ENCARD PKCS#11 (ver 4.1)
Using slot 0 with a present token (0x0)

Jak widać rozpoznał i wygrył obsługiwaną kartę.

Dla porównania bez karty.

1
2
3
4
5
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libencardp11-4.1.1.9.so -I
Cryptoki version 2.11
Manufacturer ENIGMA SOI Sp. z o.o.
Library ENCARD PKCS#11 (ver 4.1)
No slot with a token was found.

Teraz wyświetlam listę slotów.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libencardp11-4.1.1.9.so -L
Available slots:
Slot 0 (0x0): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : ENCARD
token manufacturer : Enigma SOI Sp. z o.o.
token model : IAS-ECC
token flags : login required, rng, token initialized, PIN initialized
hardware version : 5.14
firmware version : 7.0
serial num : 63XXXXXXXXXXXX04
pin min/max : 4/127
Slot 1 (0x1): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : ENCARD 2
token manufacturer : Enigma SOI Sp. z o.o.
token model : IAS-ECC
token flags : login required, rng, token initialized
hardware version : 5.14
firmware version : 7.0
serial num : 63XXXXXXXXXXXX04
pin min/max : 4/127
Slot 2 (0x2): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : ENCARD 3
token manufacturer : Enigma SOI Sp. z o.o.
token model : IAS-ECC
token flags : login required, rng, token initialized
hardware version : 5.14
firmware version : 7.0
serial num : 63XXXXXXXXXXXX04
pin min/max : 4/127

Ta karta ma 3 sloty, każdy slot może mieć przypisany inny PIN.

Wyświetlam listę obiektów publicznych w slocie (0x0), numer slotu podawany jest w notacji szestnastkowej, a w linni poleceń należy podać numer dziesiętnie!!!

1
2
3
4
5
6
7
8
9
10
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libencardp11-4.1.1.9.so --slot 0 -O
Public Key Object; RSA 2048 bits
label:
ID: 518XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX32bca
Usage: none
Access: local
Certificate Object; type = X.509 cert
label: Imię Nazwisko
subject: DN: C=PL, GN=Imi\xC4\x99, SN=Nazwisko, CN=Imi\xC4\x99 Nazwisko/serialNumber=PESEL: 00010100009, O=Ministerstwo Finans\xC3\xB3w, ST=mazowieckie, L=Warszawa/postalAddress=0*\x0C\x16ul. \xC5\x9Awi\xC4\x99tokrzyska 12\x0C\x0600-916\x0C\x08Warszawa
ID: 518XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX32bca

Dodanie opcji logowania -l pozwala na wyświetlenie także obiektów prywatnych.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libencardp11-4.1.1.9.so --slot 0 -O -l
Logging in to "ENCARD".
Please enter User PIN:
Private Key Object; RSA
label:
ID: 518XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX32bca
Usage: sign
Access: sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
label:
ID: 518XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX32bca
Usage: none
Access: local
Certificate Object; type = X.509 cert
label: Imię Nazwisko
subject: DN: C=PL, GN=Imi\xC4\x99, SN=Nazwisko, CN=Imi\xC4\x99 Nazwisko/serialNumber=PESEL: 00010100009, O=Ministerstwo Finans\xC3\xB3w, ST=mazowieckie, L=Warszawa/postalAddress=0*\x0C\x16ul. \xC5\x9Awi\xC4\x99tokrzyska 12\x0C\x0600-916\x0C\x08Warszawa
ID: 518XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX32bca

Proszę zauważyć, że ID dla obiektów klucza publicznego, klucza prywatnego i certyfikatu jest takie samo. Jest to bardzo ważne, wrapper dla PKCS#11 używany w Javie łączy te trzy obiekty, w jeden wpis w KeyStore i robi to na podstawie ID (a nie label).

KIR Carbon

Sprawdzam czy pkcs11-tool rozpoznaje bibliotekę.

1
2
3
4
5
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libccpkip11-2.01.00161.so -I
Cryptoki version 2.1
Manufacturer CryptoTech
Library Cryptoki DLL (ver 2.1)
Using slot 0 with a present token (0x0)

Teraz wyświetlam listę slotów.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libccpkip11-2.01.00161.so -L
Available slots:
Slot 0 (0x0): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : PKI Token 1
token manufacturer : CryptoTech Ltd.
token model : CC Carbon
token flags : login required, rng, token initialized, PIN initialized
hardware version : 3.2
firmware version : 6.0
serial num : 10XXXXXXXXXXXX33
pin min/max : 4/8
Slot 1 (0x1): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : PKI Token 2
token manufacturer : CryptoTech Ltd.
token model : CC Carbon
token flags : login required, rng, token initialized
hardware version : 3.2
firmware version : 6.0
serial num : 10XXXXXXXXXXXX33
pin min/max : 4/8
Slot 2 (0x2): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : PKI Token 3
token manufacturer : CryptoTech Ltd.
token model : CC Carbon
token flags : login required, rng, token initialized
hardware version : 3.2
firmware version : 6.0
serial num : 10XXXXXXXXXXXX33
pin min/max : 4/8
Slot 3 (0x3): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : QESv2
token manufacturer : CryptoTech Ltd.
token model : CC Carbon
token flags : login required, token initialized, PIN initialized, readonly
hardware version : 3.20
firmware version : 6.0
serial num : 10XXXXXXXXXXXX33
pin min/max : 6/8

Ta karta ma cztery sloty, dla tutaj dla odmiany podpis elektroniczny został umieszczony w slocie (0x3).

Obiekty w slocie 0x3

1
2
3
4
5
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libccpkip11-2.01.00161.so -O --slot 3
Certificate Object; type = X.509 cert
label: Imię Nazwisko
subject: DN: C=PL, O=Ministerstwo Finans\xC3\xB3w/serialNumber=PESEL: 00010100009, CN=Imi\xC4\x99 Nazwisko/postalAddress=0:\x0C\x12\xC5\x9Awi\xC4\x99tokrzyska 12\x0C\x0F00-916 Warszawa\x0C\x06Polska\x0C\x0Bmazowieckie, GN=Imi\xC4\x99, SN=Nazwisko
ID: edXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0b

Obiekty w slocie 0x3 widoczne po zalogowaniu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/libccpkip11-2.01.00161.so -O --slot 3 -l
Logging in to "QESv2".
Please enter User PIN:
Certificate Object; type = X.509 cert
label: Imię Nazwisko
subject: DN: C=PL, O=Ministerstwo Finans\xC3\xB3w/serialNumber=PESEL: 00010100009, CN=Imi\xC4\x99 Nazwisko/postalAddress=0:\x0C\x12\xC5\x9Awi\xC4\x99tokrzyska 12\x0C\x0F00-916 Warszawa\x0C\x06Polska\x0C\x0Bmazowieckie, GN=Imi\xC4\x99, SN=Nazwisko
ID: edXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0b
Private Key Object; RSA
label: No Friendly Name Available
ID: edXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0b
Usage: sign
warning: PKCS11 function C_GetAttributeValue(ALWAYS_AUTHENTICATE) failed: rv = CKR_ATTRIBUTE_TYPE_INVALID (0x12)

Access: none

W konsoli pojawia się błąd, ten błąd nie przeszkadza w użyciu karty.

Certum

Sprawdzam czy pkcs11-tool rozpoznaje bibliotekę.

1
2
3
4
5
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/cryptoCertum3PKCS-2.0.0.43.r2-MS.so -I
Cryptoki version 2.11
Manufacturer Unizeto Technologies SA
Library x64 PKCS #11 Cryptoki Library (ver 2.0)
Using slot 0 with a present token (0x1)

Wyświetlam dostępne sloty

1
2
3
4
5
6
7
8
9
10
11
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/cryptoCertum3PKCS-2.0.0.43.r2-MS.so -L
Available slots:
Slot 0 (0x1): Broadcom Corp 5880 [Contacted SmartCard] (0123456789ABCD) 00 00
token label : profil bezpieczny
token manufacturer : Unizeto Technologies SA
token model : cryptoCertum 3.2
token flags : login required, rng, token initialized, PIN initialized
hardware version : 5.0
firmware version : 1.0
serial num : 29XXXXXXXXXX08
pin min/max : 4/8

Obiekty w slocie 0x1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/cryptoCertum3PKCS-2.0.0.43.r2-MS.so --slot 1 -O
Public Key Object; RSA 2048 bits
label: Imię Nazwisko
ID: 1bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6e
Usage: encrypt, verify, wrap
Access: local
Public Key Object; RSA 2048 bits
label:
ID: 94XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX97
Usage: encrypt, verify, wrap
Access: local
Public Key Object; RSA 2048 bits
label:
ID: 28XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4e
Usage: encrypt, verify, wrap
Access: local
Certificate Object; type = X.509 cert
label: Imię Nazwisko
subject: DN: CN=Imi\xC4\x99 Nazwisko, GN=Imi\xC4\x99, SN=Nazwisko/serialNumber=PNOPL-00010100009, C=PL
ID: 1bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6e

Tutaj widać, że Certum generuje 3 klucze na karcie, a po wystawieniu certyfikatu kwalifikowanego, dogrywa certyfikat do karty.

Obiekty w slocie 0x1 widoczne po zalogowaniu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
ksm@ksm-7530/tmp $ pkcs11-tool --module /tmp/cryptoCertum3PKCS-2.0.0.43.r2-MS.so --slot 1 -O -l
Logging in to "profil bezpieczny".
Please enter User PIN:
Private Key Object; RSA
label: Imię Nazwisko
ID: 1bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6e
Usage: decrypt, sign, unwrap
warning: PKCS11 function C_GetAttributeValue(ALWAYS_AUTHENTICATE) failed: rv = CKR_ATTRIBUTE_TYPE_INVALID (0x12)

Access: sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
label: Imię Nazwisko
ID: 1bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6e
Usage: encrypt, verify, wrap
Access: local
Private Key Object; RSA
label:
ID: 94XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX97
Usage: decrypt, sign, unwrap
warning: PKCS11 function C_GetAttributeValue(ALWAYS_AUTHENTICATE) failed: rv = CKR_ATTRIBUTE_TYPE_INVALID (0x12)

Access: sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
label:
ID: 94XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX97
Usage: encrypt, verify, wrap
Access: local
Private Key Object; RSA
label:
ID: 28XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4e
Usage: decrypt, sign, unwrap
warning: PKCS11 function C_GetAttributeValue(ALWAYS_AUTHENTICATE) failed: rv = CKR_ATTRIBUTE_TYPE_INVALID (0x12)

Access: sensitive, always sensitive, never extractable, local
Public Key Object; RSA 2048 bits
label:
ID: 28XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4e
Usage: encrypt, verify, wrap
Access: local
Certificate Object; type = X.509 cert
label: Imię Nazwisko
subject: DN: CN=Imi\xC4\x99 Nazwisko, GN=Imi\xC4\x99, SN=Nazwisko/serialNumber=PNOPL-00010100009, C=PL
ID: 1bXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX6e

Podsumowanie

pkcs11-tool można użyć aby sprawdzić, czy biblioteka pkcs11, którą posiadamy współpracuje z naszą kartą. Należy sprawdzić pod jakim numerem slotu jest zapisany nasz certyfikat kwalifikowany lub pieczęć elektroniczna. Należy też sprawdzić czy klucz prywatny i certyfikat mają takie same ID (na kartach podpisu elektronicznego, które widziałem tak było, ale klucze generowane na HSM, mogą nie mieć tej informacji).