poniedziałek, 29 czerwca 2026

STM32H7 - OpenSSL - Generowanie certyfikatu

W tym poście chciałbym opisać sposób generowania certyfikatu do HTTPS czy TLS. 


Do tego celu potrzebujemy biblioteki OpenSSL. Chyba najprościej użyć jej przez Git Bash.

Na samym początku generujemy CA, czyli stajemy się trochę własnym urzędem certyfikacji. CA służy do podpisania certyfikatu serwera. Nie będzie on odrazu rozpoznawalny przez przeglądarkę jako bezpieczny, ale po dodaniu go w systemie będziemy widzieć jak by był w pełni poprawnie podpisany. 

  1. openssl genrsa -out test-device-ca.key 4096

Gdy już mam klucz to generuje ceryfikat:

  1. $ MSYS_NO_PATHCONV=1 openssl req -x509 -new -nodes \
  2.   -key test-device-ca.key \
  3.   -sha256 \
  4.   -days 3650 \
  5.   -out test-device-ca.crt \
  6.   -subj "/O=test/CN=test-device-CA"

Teraz w folderze są dwa pliki:


Teraz tworzymy plik konfiguracyjny dla certyfikatu:

  1. [ req ]
  2. default_bits       = 2048
  3. prompt             = no
  4. default_md         = sha256
  5. distinguished_name = dn
  6. req_extensions     = req_ext
  7.  
  8. [ dn ]
  9. O  = TEST
  10. CN = 150.153.100.160
  11.  
  12. [ req_ext ]
  13. subjectAltName = @alt_names
  14.  
  15. [ alt_names ]
  16. IP.1 = 150.153.100.160
  17.  
  18. [ v3_server ]
  19. keyUsage = digitalSignature, keyEncipherment
  20. extendedKeyUsage = serverAuth
  21. subjectAltName = @alt_names

Zapisałem go pod nazwą server_conf.cnf. Można w nim wylistować adresy IP, jeśli ceryfikat ma działać dla kilku urządzeń. Przykładowo mogło by to wyglądać tak:

  1. [ alt_names ]
  2. IP.1 = 150.153.100.160
  3. IP.2 = 192.168.1.16
  4. DNS.1 = nazwa_x.local
  5. DNS.2 = nazwa_y.local

CA został ustawiony na 4096 bitów, natomiast certyfikat serwera na 2048 bitów. Zmniejszy to obciążenie urządzenia podczas komunikacji. 

Teraz generuje nowy klucz:

  1. openssl genrsa -out stm-server.key 2048

A teraz nowy CSR:

  1. openssl req -new -key stm-server.key -out stm-server.csr -config server_conf.cnf

Teraz podpisanie certyfikatu przez wygenerowane wcześniej CA:

  1. $ openssl x509 -req \
  2.   -in stm-server.csr \
  3.   -CA test-device-ca.crt \
  4.   -CAkey test-device-ca.key \
  5.   -CAcreateserial \
  6.   -out stm-server.crt \
  7.   -days 3650 \
  8.   -sha256 \
  9.   -extfile server_conf.cnf \
  10.   -extensions v3_server

Komenda składa się z kilku flag:
  • -req - informacja dla OpenSSL, że przekazujemy żądanie podpisania certyfikatu
  • -in - wskazuje plik wejściowy, czyli żadanie podpisania certyfikatu
  • -CA - wskazuje certyfikat
  • -CAkey - wskazuje klucz prywatny urzędu CA
  • -CAcreateserial - tworzy plik z unikalnym numerem seryjnym (.srl)
  • -out - nazwa pliku do którego certyfikat zostanie wpisany
  • -days - okres ważności certyfikatu
  • -sha256 - nazwa algorytmu HASH który zostanie użyty do podpisu kryptograficznego. 
  • -extfile - plik konfiguracyjny zewnętrzny, z którego ma zostać pobrane dodatkowe rozszerzenie dla certyfikatu. 
  • -extentsions - przekazuje nazwę sekcji, z pliku konfiguracyjnego, która ma zostać wykorzystana.

Jeśli nie wyświetliły się żadne błędy to przechodzimy do weryfikacji:

  1. $ openssl verify -CAfile test-device-ca.crt stm-server.crt

Jeśli wszystko przeszło poprawnie, to wyświetli się status:

  1. stm-server.crt: OK
Można też wyświetlić pełne dane z certyfikatu. 

  1. openssl x509 -in stm-server.crt -noout -text

Powyższa komenda odczyta i wyświetli zawartość certyfikatu w czytelnej formie:

  1. Certificate:
  2.     Data:
  3.         Version: 3 (0x2)
  4.         Serial Number:
  5.             1c:5f:ed:47:fc:48:80:0f:62:b8:18:51:de:b9:51:5e:a8:dd:20:03
  6.         Signature Algorithm: sha256WithRSAEncryption
  7.         Issuer: O=test, CN=test-device-CA
  8.         Validity
  9.             Not Before: Jun 22 07:14:45 2026 GMT
  10.             Not After : Jun 19 07:14:45 2036 GMT
  11.         Subject: O=TEST, CN=150.153.100.160
  12.         Subject Public Key Info:
  13.             Public Key Algorithm: rsaEncryption
  14.                 Public-Key: (2048 bit)
  15.                 Modulus:
  16.                     00:92:bc:ca:76:2c:6d:9b:be:11:10:e7:18:a0:da:
  17.                     d8:d3:a9:df:c9:f7:59:89:ba:8d:bf:b6:54:09:8f:
  18.                     a3:66:fd:af:89:1b:06:62:94:56:f5:33:52:9f:1c:
  19.                     61:51:77:e9:aa:b6:bc:91:1f:82:2f:90:55:7c:1d:
  20.                     30:12:fd:83:f1:a5:f3:36:fa:22:ba:eb:c7:1a:e2:
  21.                     af:5a:1d:b0:71:30:34:dc:d3:59:8c:5c:d3:21:c2:
  22.                     9f:8e:ff:34:fa:a3:e3:8b:85:fd:72:54:fa:a3:0d:
  23.                     0a:62:a3:bb:bf:e7:8a:b1:52:6a:5e:1c:ba:9c:c8:
  24.                     8a:bb:e5:9b:c1:87:70:12:76:bc:e1:a5:86:e8:a7:
  25.                     d2:e2:b9:72:f5:85:db:7f:86:55:fb:88:14:6c:96:
  26.                     eb:4d:ce:fa:5a:e0:44:0b:ae:8b:9c:2c:a9:71:03:
  27.                     28:1b:b8:c8:56:a1:12:da:62:93:0c:88:a4:9e:52:
  28.                     75:74:54:46:a5:a1:83:72:c4:aa:f1:78:10:e2:08:
  29.                     47:7a:34:f6:43:01:d4:8e:7a:3a:4e:b6:85:94:c9:
  30.                     58:dc:21:a8:53:61:d4:0d:2f:29:1a:41:f2:b6:d2:
  31.                     16:65:04:a7:2e:c9:82:56:ba:31:12:e6:11:4e:ac:
  32.                     15:86:d9:0d:f6:14:d4:5a:d4:9a:92:0b:c5:76:fb:
  33.                     50:a9
  34.                 Exponent: 65537 (0x10001)
  35.         X509v3 extensions:
  36.             X509v3 Key Usage:
  37.                 Digital Signature, Key Encipherment
  38.             X509v3 Extended Key Usage:
  39.                 TLS Web Server Authentication
  40.             X509v3 Subject Alternative Name:
  41.                 IP Address:150.153.100.160
  42.             X509v3 Subject Key Identifier:
  43.                 39:27:04:25:3B:D5:61:16:D2:71:57:57:9A:FC:AB:DF:1D:6D:95:EC
  44.             X509v3 Authority Key Identifier:
  45.                 6F:C0:81:CD:03:32:7B:C3:17:BC:BD:02:FE:5F:70:AA:68:D6:66:2D
  46.     Signature Algorithm: sha256WithRSAEncryption
  47.     Signature Value:
  48.         5b:e9:84:85:7b:97:58:31:55:c2:69:36:8d:2c:39:60:de:d3:
  49.         15:8d:1e:fd:24:31:ae:53:a7:c9:05:44:2b:78:8f:7b:6d:7a:
  50.         80:ed:d5:c4:e6:3e:70:f2:b2:bc:6f:a0:c0:f6:9f:77:ef:e8:
  51.         d6:03:25:1f:13:b1:ed:95:92:86:fd:12:3d:58:18:73:5a:f9:
  52.         16:f1:0c:cd:cc:c0:4b:ac:33:d4:7e:b0:52:2c:97:45:f1:b2:
  53.         72:c4:42:cb:43:ee:ae:ca:10:35:3f:dc:3d:33:14:04:79:1b:
  54.         1a:44:53:97:57:53:08:74:30:c8:89:0e:04:6a:3c:0e:d8:53:
  55.         65:92:bb:02:bc:f0:ac:9f:d9:0a:49:f3:86:9e:08:b6:b6:1b:
  56.         d2:d4:9e:e4:82:ca:a2:55:01:e5:10:57:25:50:6f:bb:52:84:
  57.         2a:7f:de:9f:a4:49:55:49:9d:ec:59:25:47:03:ec:dc:3b:36:
  58.         ff:aa:2f:8b:54:69:1f:78:09:1d:bd:f6:b4:3f:45:09:3a:be:
  59.         22:0c:d6:4e:c7:7c:ee:15:3a:57:bc:c8:6a:86:bd:a5:98:5d:
  60.         15:31:19:b4:eb:da:f5:2f:e4:f1:1b:81:61:9d:9f:08:94:4e:
  61.         a1:d2:f0:ae:be:e6:94:5c:2a:10:be:23:e1:26:35:fb:e2:7c:
  62.         0d:ef:ad:cb:e1:56:33:cb:78:b5:4c:9c:e0:a3:84:04:4a:c7:
  63.         9e:ca:56:54:30:76:b1:cc:ae:f3:ce:8a:96:b3:2b:ce:ff:08:
  64.         31:64:87:66:cc:98:50:3f:bc:1c:73:86:2c:7b:2e:f9:5c:55:
  65.         d1:3c:37:da:a5:8f:48:2e:24:07:59:7d:30:9f:50:69:5f:09:
  66.         0c:cc:2f:18:fa:7a:c3:0c:a2:62:ee:ab:bf:79:54:db:4b:59:
  67.         3d:5d:4f:d6:7a:02:05:5e:35:8a:09:ff:d6:99:63:8c:b6:02:
  68.         bc:ab:1f:1e:26:ba:6d:c5:46:83:46:b2:74:ee:37:09:a7:22:
  69.         cc:db:64:6f:b8:93:3c:7b:0f:44:6f:75:dd:a1:83:17:b6:e1:
  70.         b8:31:a8:da:fc:c8:8b:17:39:d1:f5:ab:2f:6e:e0:cc:30:bb:
  71.         66:40:15:14:d8:59:69:47:67:e6:14:fb:96:22:63:e5:c9:2c:
  72.         82:b1:0c:de:e0:b5:f7:07:f6:f4:8f:ca:4b:cc:f7:33:64:0e:
  73.         9c:8f:54:82:9c:bd:f7:d2:3b:a9:49:6a:85:16:09:51:56:ac:
  74.         7d:2b:79:26:a0:1f:23:09:da:e6:f6:26:dc:93:4c:ab:8b:10:
  75.         ad:08:d9:50:c1:42:ab:00:7a:2f:fa:d0:68:79:2b:98:08:2b:
  76.         e5:7d:b4:18:22:96:fb:c0

Powyżej widać zdekodowany certyfikat X.509. Można tu sprawdzić takie informacje jak kto wystawił ten certyfikat i dla kogo, okres ważności czy przeznaczenie ceryfikatu.

Przeglądarki sprawdzają pole Subject Alternative Name. Sam CN nie wystarczy by urządzenie było rozpoznane po zainstalowaniu certyfikatu. Jeśli strona jest uruchamiana po adresie IP, to adres IP musi znajdować się w sekcji subjectAltName jako IP.x. 

Dodatkowo można też zweryfikować zgodność klucza z certyfikatem:

  1. openssl x509 -noout -modulus -in stm-server.crt | openssl md5
  2. openssl rsa  -noout -modulus -in stm-server.key | openssl md5

Wynik obu komend powinien być identyczny:

  1. $ openssl x509 -noout -modulus -in stm-server.crt | openssl md5
  2. MD5(stdin)= 6589b7e132543a6e2785c9635d0917de
  3.  
  4. $ openssl rsa  -noout -modulus -in stm-server.key | openssl md5
  5. MD5(stdin)= 6589b7e132543a6e2785c9635d0917de

Pełny komplet plików powinien wyglądać tak:


W folderze są dwa pliki stm-server.crt oraz stm-server.key. Należy ich zawartość przerobić na ciąg rozpoznawalny przez biblioteki. Aby to wykonać automatycznie użyje następującego skryptu w python:

  1. def pem_to_c_string(path, var_name):
  2.     with open(path, "r", encoding="ascii") as f:
  3.         lines = f.read().splitlines()
  4.  
  5.     print(f'const char {var_name}[] =')
  6.     for line in lines:
  7.         print(f'"{line}\\r\\n"')
  8.     print(";")
  9.  
  10. pem_to_c_string("stm-server.crt", "mbedtls_server_certificate_https")
  11. pem_to_c_string("stm-server.key", "mbedtls_certificate_server_private_key_https")

Który po uruchomieniu:

  1. py .\pem_to_c.py

Wyświetli w terminalu wynik który można przekleić bezpośrednio do STM'a:

  1. > py .\pem_to_c.py
  2. const char mbedtls_server_certificate_https[] =
  3. "-----BEGIN CERTIFICATE-----\r\n"
  4. "MIIEVDCCAjygAwIBAgIUHF/tR/xIgA9iuBhR3rlRXqjdIAMwDQYJKoZIhvcNAQEL\r\n"
  5. "BQAwKDENMAsGA1UECgwEdGVzdDEXMBUGA1UEAwwOdGVzdC1kZXZpY2UtQ0EwHhcN\r\n"
  6. "MjYwNjIyMDcxNDQ1WhcNMzYwNjE5MDcxNDQ1WjApMQ0wCwYDVQQKDARURVNUMRgw\r\n"
  7. "FgYDVQQDDA8xNTAuMTUzLjEwMC4xNjAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw\r\n"
  8. "ggEKAoIBAQCSvMp2LG2bvhEQ5xig2tjTqd/J91mJuo2/tlQJj6Nm/a+JGwZilFb1\r\n"
  9. "M1KfHGFRd+mqtryRH4IvkFV8HTAS/YPxpfM2+iK668ca4q9aHbBxMDTc01mMXNMh\r\n"
  10. "wp+O/zT6o+OLhf1yVPqjDQpio7u/54qxUmpeHLqcyIq75ZvBh3ASdrzhpYbop9Li\r\n"
  11. "uXL1hdt/hlX7iBRslutNzvpa4EQLroucLKlxAygbuMhWoRLaYpMMiKSeUnV0VEal\r\n"
  12. "oYNyxKrxeBDiCEd6NPZDAdSOejpOtoWUyVjcIahTYdQNLykaQfK20hZlBKcuyYJW\r\n"
  13. "ujES5hFOrBWG2Q32FNRa1JqSC8V2+1CpAgMBAAGjdTBzMAsGA1UdDwQEAwIFoDAT\r\n"
  14. "BgNVHSUEDDAKBggrBgEFBQcDATAPBgNVHREECDAGhwSWmWSgMB0GA1UdDgQWBBQ5\r\n"
  15. "JwQlO9VhFtJxV1ea/KvfHW2V7DAfBgNVHSMEGDAWgBRvwIHNAzJ7wxe8vQL+X3Cq\r\n"
  16. "aNZmLTANBgkqhkiG9w0BAQsFAAOCAgEAW+mEhXuXWDFVwmk2jSw5YN7TFY0e/SQx\r\n"
  17. "rlOnyQVEK3iPe216gO3VxOY+cPKyvG+gwPafd+/o1gMlHxOx7ZWShv0SPVgYc1r5\r\n"
  18. "FvEMzczAS6wz1H6wUiyXRfGycsRCy0PursoQNT/cPTMUBHkbGkRTl1dTCHQwyIkO\r\n"
  19. "BGo8DthTZZK7ArzwrJ/ZCknzhp4ItrYb0tSe5ILKolUB5RBXJVBvu1KEKn/en6RJ\r\n"
  20. "VUmd7FklRwPs3Ds2/6ovi1RpH3gJHb32tD9FCTq+IgzWTsd87hU6V7zIaoa9pZhd\r\n"
  21. "FTEZtOva9S/k8RuBYZ2fCJROodLwrr7mlFwqEL4j4SY1++J8De+ty+FWM8t4tUyc\r\n"
  22. "4KOEBErHnspWVDB2scyu886KlrMrzv8IMWSHZsyYUD+8HHOGLHsu+VxV0Tw32qWP\r\n"
  23. "SC4kB1l9MJ9QaV8JDMwvGPp6wwyiYu6rv3lU20tZPV1P1noCBV41ign/1pljjLYC\r\n"
  24. "vKsfHia6bcVGg0aydO43CacizNtkb7iTPHsPRG913aGDF7bhuDGo2vzIixc50fWr\r\n"
  25. "L27gzDC7ZkAVFNhZaUdn5hT7liJj5cksgrEM3uC19wf29I/KS8z3M2QOnI9Ugpy9\r\n"
  26. "99I7qUlqhRYJUVasfSt5JqAfIwna5vYm3JNMq4sQrQjZUMFCqwB6L/rQaHkrmAgr\r\n"
  27. "5X20GCKW+8A=\r\n"
  28. "-----END CERTIFICATE-----\r\n"
  29. ;
  30. const char mbedtls_certificate_server_private_key_https[] =
  31. "-----BEGIN PRIVATE KEY-----\r\n"
  32. "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCSvMp2LG2bvhEQ\r\n"
  33. "5xig2tjTqd/J91mJuo2/tlQJj6Nm/a+JGwZilFb1M1KfHGFRd+mqtryRH4IvkFV8\r\n"
  34. "HTAS/YPxpfM2+iK668ca4q9aHbBxMDTc01mMXNMhwp+O/zT6o+OLhf1yVPqjDQpi\r\n"
  35. "o7u/54qxUmpeHLqcyIq75ZvBh3ASdrzhpYbop9LiuXL1hdt/hlX7iBRslutNzvpa\r\n"
  36. "4EQLroucLKlxAygbuMhWoRLaYpMMiKSeUnV0VEaloYNyxKrxeBDiCEd6NPZDAdSO\r\n"
  37. "ejpOtoWUyVjcIahTYdQNLykaQfK20hZlBKcuyYJWujES5hFOrBWG2Q32FNRa1JqS\r\n"
  38. "C8V2+1CpAgMBAAECggEAEhKsZZh0ghSLfc9W1FYME2rWeEXNuoXWiFystlZBkBFy\r\n"
  39. "FbMVSt4+JRp2hEgesOXx6t+xszakJldSvhQKvCYLIp/XyEdP8IGSfvxZUGI8fX5s\r\n"
  40. "Xl/uJTh4HS3/UMGcXPwDTkeZJyQyEBPOugY0XU8ngQ5XcUK81ctp8flWYSRdMHrN\r\n"
  41. "adCZCITGf8FmdcSnJE3QwVufgQj9Mqem+E5WkIoPy5tiQeqDcjrBy+bnrT/Wc/Ul\r\n"
  42. "j9GdR9PPhoxeBj8RevJ7vICqw+0Ku6Njsx7WYTWVhixfLQHkDxknNUDdCxpGSRuH\r\n"
  43. "oW6IsAxq7sit3ovLlTcDLAsNX5EL9u8PfCJX/ZkMsQKBgQDFODsxdhrpQ/wbSQxi\r\n"
  44. "7UvXk4+DYutaP8cajhjamOLP3DlZW2QhYEMK8JyHfz1nxFsBHneDy+Ri9oevWGTn\r\n"
  45. "CQzgl/uPSCDvaZZTl/uPJGZHMLvQWsNy3j0wRZ1+fpAZnZLN6CLBwCTbxtP9t3k9\r\n"
  46. "x4Q8viZke2AjWEV43ZqP7rNueQKBgQC+eMq3eZrtFX7yui8H2W0a7CGoZRXI7Jub\r\n"
  47. "YEGQBpeJIJGTRW9Y2cfvv8HOMdDoWpLldLnBRkasIrSnueDJbgYFCtEfVH3Adb5Z\r\n"
  48. "QFeWdTSsBYmQT6L9Hr6cUlH0D7PJRMQgQy//qnZc8/bw+W2ji/UcOm7Rd96vZqzB\r\n"
  49. "j/mv2/OnsQKBgQCpV3Q0LzZCT1bc0udo1lrF+3VCGqD9uD+tBJBAuwAd/PndSUT8\r\n"
  50. "B5zpetrc2ZuPSyHdHxz+NQehFhBBtoPFgZbmDno5eHSXPjGPC7Q8H8QWorjR2e1y\r\n"
  51. "53LgzRXDtMbkx9FzLj0R4nuDnwEOHQlky7k3MwriQrG1B6l3c8iwiATX+QKBgAuu\r\n"
  52. "9SBUAUDRtLvG1+OvXpXsLhRaPv/YI6NgQCVJgjoTGVrjQ3U7xpvaM1UmkR3vkFsq\r\n"
  53. "0codOXCNoG85Y6R3bz8X7sPxNtV7Y3WuELFV9ykmHc4QVHsaS67jDcveurR5113z\r\n"
  54. "QRp5plEFVfxqEGObzikxHGMU6z/vGGG3JyW2ZDfBAoGBALbFLw5LL23BPE8PWGIf\r\n"
  55. "jaNjm73qpKenU5FvLbLhFVx1q6fDmJg+g4HPbu12f+B+WPnGO/3W7+fKv1XCgVL8\r\n"
  56. "bQZ9M9f7+ld9Xbq/OVYZYAffbHxpTWXn4heBlWvnqGRQQ04I0/TUC3W+gWm+lcfb\r\n"
  57. "pjw3TcrO5g6RcDVKyXwsvyN7\r\n"
  58. "-----END PRIVATE KEY-----\r\n"

Tak zdeklarowany certyfikat będzie umieszczony przez kompilator w pamięci Flash STM'a. Do RAM trafi podczas parsowania. 

Należy pamiętać, że przekazywany certyfikat powinien zawierać znak NUL. Z tego powodu często przekazuje się długość przekazuje się jako srlen(certyfikat) + 1. 

  1. ret = mbedtls_x509_crt_parse(&server_cert,
  2.         (const unsigned char*)mbedtls_server_certificate_https,
  3.         strlen(mbedtls_server_certificate_https) + 1);
  4.  
  5. //...
  6. //...
  7.  
  8. ret = mbedtls_pk_parse_key(&server_key,
  9.         (const unsigned char*)mbedtls_certificate_server_key_pass_https,
  10.         strlen(mbedtls_certificate_server_key_pass_https) + 1,
  11.         NULL, 0);

Oczywiście dobrze by było taki certyfikat przechowywać w sposób który umożliwi jego podmianę, jeśli zajdzie taka potrzeba np. zaszyfrowany w zewnętrznej pamięci flash. 

Korzystając z biblioteki OpenSSL można wykonać też test komunikacji. Przykładowo w taki sposób:

  1. openssl s_client -connect 150.153.100.160:443 -CAfile test-device-ca.crt

Jak już jest dodany certyfikat to możemy go dołożyć w systemie by nie wyświetlała się następująca informacja:


Na screenie widać błąć NET::ERR_CERT_AUTHORITY_INVALID. Czyli certyfikat jest wystawiony przez urząd, któremu system lub przeglądarka nie ufa. 

Sprawdzę teraz jak powinniśmy wchodzić na stronę by udało się bez błędów:

  1. $ openssl x509 -in stm-server.crt -noout -subject -issuer -ext subjectAltName
  2. subject=O=TEST, CN=150.153.100.160
  3. issuer=O=test, CN=test-device-CA
  4. X509v3 Subject Alternative Name:
  5.     IP Address:150.153.100.160

Teraz instalacja certyfikatu w systemie przez PowerShell:

  1. Import-Certificate -FilePath "C:\sciezka\test-device-ca.crt" -CertStoreLocation Cert:\LocalMachine\Root

Do magazynu certyfikatów instalujemy certyfikat CA, czyli test-device-ca.crt. Nie instalujemy certyfikatu serwera stm-server.crt 

Powyższa metoda wymaga uprawnień administratora i działa dla całego komputera. Jeśli chcemy zainstalować certyfikat tylko dla bieżącego użytkownika to należy użyć następującej komendy:

  1. Import-Certificate -FilePath "C:\sciezka\test-device-ca.crt" -CertStoreLocation Cert:\CurrentUser\Root

Jak wszystko pójdzie dobrze to wyświetli się odpowiedź:


Po wejściu na stronę, nie będzie już błędu. Certyfikat będzie w pełni rozpoznawany na komputerze.