Es ist
Zeit, Ihnen zu erzählen, wie das PyKCS11-Projekt um Unterstützung für russische Kryptografie erweitert wurde
. Alles begann, als ich auf eine
Korrespondenz zwischen dem Entwickler des PyKCS11-Projekts und potenziellen Verbrauchern über die mögliche Unterstützung von GOST R 34.10-2012-Algorithmen stieß. In dieser Korrespondenz sagte der
Autor von PkCS11 , dass er die Unterstützung russischer Kryptoalgorithmen erst dann einbeziehen werde, wenn sie standardisiert sind.
Er drückte mir dieselbe Idee aus, als ich ihn darum bat. Und nicht nur, um es zu tun, sondern um den entsprechenden Programmcode zu senden:
Danach hielt ich es für möglich, den Code in mein Repository zu teilen und die entsprechenden Änderungen daran vorzunehmen. Das PyKCS11-Projekt mit russischer Kryptografieunterstützung ist hier .
I. Unterstützung für russische Kryptoalgorithmen hinzufügen
Also, was wurde getan? Ich habe tatsächlich einen der Tipps des Autors des PyKCS11-Projekts befolgt:
Ich kann Ihnen vorschlagen, eine PyKCS11_GOST.py-Datei mit den gewünschten konstanten Namen und Funktionen zu erstellen, um PyKCS11 mit GOST-Unterstützung zu erweitern.
(Ich könnte vorschlagen, dass Sie eine PyKCS11_GOST.py-Datei mit den Namen der Konstanten und Funktionen erstellen, die Sie PyKCS11 erweitern möchten, um GOST zu unterstützen.)
Alle von TC-26 für PKCS # 11 genehmigten Konstanten wurden in einer Datei pkcs11t_gost.h konsolidiert, die sich im Ordner src befindet:
//-26
#define NSSCK_VENDOR_PKCS11_RU_TEAM 0xd4321000
#define NSSCK_VENDOR_PKSC11_RU_TEAM NSSCK_VENDOR_PKCS11_RU_TEAM
#define CK_VENDOR_PKCS11_RU_TEAM_TC26 NSSCK_VENDOR_PKCS11_RU_TEAM
#define CKK_GOSTR3410_512 0xd4321003UL
#define CKK_KUZNYECHIK 0xd4321004UL
#define CKK_MAGMA 0xd4321005UL
#define CKK_GOSTR3410_256 0xd4321006UL
#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411_TC26_V1 0xd4321801UL
#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411_2012_256 0xd4321002UL
#define CKP_PKCS5_PBKD2_HMAC_GOSTR3411_2012_512 0xd4321003UL
#define CKM_GOSTR3410_512_KEY_PAIR_GEN 0xd4321005UL
#define CKM_GOSTR3410_512 0xd4321006UL
#define CKM_GOSTR3410_WITH_GOSTR3411 0x00001202
#define CKM_GOSTR3410_WITH_GOSTR3411_12_256 0xd4321008UL
#define CKM_GOSTR3410_WITH_GOSTR3411_12_512 0xd4321009UL
#define CKM_GOSTR3410_12_DERIVE 0xd4321007UL
#define CKM_GOSR3410_2012_VKO_256 0xd4321045UL
#define CKM_GOSR3410_2012_VKO_512 0xd4321046UL
#define CKM_KDF_4357 0xd4321025UL
#define CKM_KDF_GOSTR3411_2012_256 0xd4321026UL
#define CKM_KDF_TREE_GOSTR3411_2012_256 0xd4321044UL
#define CKM_GOSTR3410_PUBLIC_KEY_DERIVE 0xd432100AUL
#define CKM_LISSI_GOSTR3410_PUBLIC_KEY_DERIVE 0xd4321037UL
#define CKM_GOST_GENERIC_SECRET_KEY_GEN 0xd4321049UL
#define CKM_GOST_CIPHER_KEY_GEN 0xd4321048UL
#define CKM_GOST_CIPHER_ECB 0xd4321050UL
#define CKM_GOST_CIPHER_CBC 0xd4321051UL
#define CKM_GOST_CIPHER_CTR 0xd4321052UL
#define CKM_GOST_CIPHER_OFB 0xd4321053UL
#define CKM_GOST_CIPHER_CFB 0xd4321054UL
#define CKM_GOST_CIPHER_OMAC 0xd4321055UL
#define CKM_GOST_CIPHER_KEY_WRAP 0xd4321059UL
#define CKM_GOST_CIPHER_ACPKM_CTR 0xd4321057UL
#define CKM_GOST_CIPHER_ACPKM_OMAC 0xd4321058UL
#define CKM_GOST28147_PKCS8_KEY_WRAP 0xd4321036UL
#define CKM_GOST_CIPHER_PKCS8_KEY_WRAP 0xd432105AUL
#define CKM_GOST28147_CNT 0xd4321825UL
#define CKM_KUZNYECHIK_KEY_GEN 0xd4321019UL
#define CKM_KUZNYECHIK_ECB 0xd432101AUL
#define CKM_KUZNYECHIK_CBC 0xd432101EUL
#define CKM_KUZNYECHIK_CTR 0xd432101BUL
#define CKM_KUZNYECHIK_OFB 0xd432101DUL
#define CKM_KUZNYECHIK_CFB 0xd432101CUL
#define CKM_KUZNYECHIK_OMAC 0xd432101FUL
#define CKM_KUZNYECHIK_KEY_WRAP 0xd4321028UL
#define CKM_KUZNYECHIK_ACPKM_CTR 0xd4321042UL
#define CKM_KUZNYECHIK_ACPKM_OMAC 0xd4321043UL
#define CKM_MAGMA_KEY_GEN 0xd432102AUL
#define CKM_MAGMA_ECB 0xd4321018UL
#define CKM_MAGMA_CBC 0xd4321023UL
#define CKM_MAGMA_CTR 0xd4321020UL
#define CKM_MAGMA_OFB 0xd4321022UL
#define CKM_MAGMA_CFB 0xd4321021UL
#define CKM_MAGMA_OMAC 0xd4321024UL
#define CKM_MAGMA_KEY_WRAP 0xd4321029UL
#define CKM_MAGMA_ACPKM_CTR 0xd4321040UL
#define CKM_MAGMA_ACPKM_OMAC 0xd4321041UL
#define CKM_GOSTR3411_12_256 0xd4321012UL
#define CKM_GOSTR3411_12_512 0xd4321013UL
#define CKM_GOSTR3411_12_256_HMAC 0xd4321014UL
#define CKM_GOSTR3411_12_512_HMAC 0xd4321015UL
#define CKM_PBA_GOSTR3411_WITH_GOSTR3411_HMAC 0xd4321035UL
#define CKM_TLS_GOST_KEY_AND_MAC_DERIVE 0xd4321033UL
#define CKM_TLS_GOST_PRE_MASTER_KEY_GEN 0xd4321031UL
#define CKM_TLS_GOST_MASTER_KEY_DERIVE 0xd4321032UL
#define CKM_TLS_GOST_PRF 0xd4321030UL
#define CKM_TLS_GOST_PRF_2012_256 0xd4321016UL
#define CKM_TLS_GOST_PRF_2012_512 0xd4321017UL
#define CKM_TLS_TREE_GOSTR3411_2012_256 0xd4321047UL
Diese Liste enthält Mechanismen, die sowohl für die Bildung und Überprüfung von Signaturen gemäß (GOST R 34.10-2012) GOST R 34.10-2012 als auch für die Verschlüsselung (GOST R 34.12-2015 und GOST R 34.13-2015 - Verschlüsselungsalgorithmen Grasshopper und Magma) erforderlich sind. . Natürlich gibt es hier auch Hashing-Algorithmen für GOST R 34.11-2012.
Damit die GOST-Konstanten in den Modulerstellungsprozess einbezogen werden können, muss der Datei pkcs11t_gost.h der Datei pkcs11.i (Datei für SWIG) eine include-Anweisung hinzugefügt werden.
%include "pkcs11t_gost.h"
vor dem Bediener
%include "pkcs11lib.h"
Das ist aber noch nicht alles. In der Methode getMechanismList (Skript PKCS11 / __ init__.py) wird die Ausgabe von Mechanismen blockiert, deren Code größer als CKM_VENDOR_DEFINED ist (genau darüber schreibt der Autor des PyKCS11-Projekts) (0x80000000L). Beachten Sie, dass GOST-Konstanten für neue Algorithmen unter diese Einschränkung fallen. Es ist notwendig, es zumindest für GOSTs zu entfernen, daher werden wir den Code der getMechanismList-Methode durch einen neuen ersetzen:
def getMechanismList(self, slot):
"""
C_GetMechanismList
:param slot: slot number returned by :func:`getSlotList`
:type slot: integer
:return: the list of available mechanisms for a slot
:rtype: list
"""
mechanismList = PyKCS11.LowLevel.ckintlist()
rv = self.lib.C_GetMechanismList(slot, mechanismList)
if rv != CKR_OK:
raise PyKCS11Error(rv)
m = []
#
#define NSSCK_VENDOR_PKCS11_RU_TEAM 0xd4321000
for x in range(len(mechanismList)):
mechanism = mechanismList[x]
if mechanism >= CKM_VENDOR_DEFINED:
if mechanism >= CKM_VENDOR_DEFINED and mechanism < 0xd4321000:
k = 'CKM_VENDOR_DEFINED_0x%X' % (mechanism - CKM_VENDOR_DEFINED)
CKM[k] = mechanism
CKM[mechanism] = k
m.append(CKM[mechanism])
return m
#ORIGINAL
# for x in range(len(mechanismList)):
# mechanism = mechanismList[x]
# if mechanism >= CKM_VENDOR_DEFINED:
# k = 'CKM_VENDOR_DEFINED_0x%X' % (mechanism - CKM_VENDOR_DEFINED)
# CKM[k] = mechanism
# CKM[mechanism] = k
# m.append(CKM[mechanism])
# return m
Beachten Sie auch, dass das Modul zwar alle Mechanismen enthält, die in den Include-Dateien pkcs11t.h und pkcs11t_gost.h für pkcs11 v.2.40 definiert sind, jedoch nicht alle dieser Mechanismen implementiert werden können. Das Problem ist, dass einige von ihnen eine bestimmte Parameterstruktur erfordern. Dies gilt insbesondere für den Mechanismus CKM_RSA_PKCS_OAEP, für den Parameter in Form einer CK_RSA_PKCS_OAEP_PARAMS-Struktur erforderlich sind, und für den Mechanismus CKM_PKCS5_PBKD2, der Parameter in Form einer CK_PKCS5_PBKD2_PARKP. Es gibt auch andere Mechanismen. Da der Autor jedoch separate Strukturen für separate Mechanismen implementiert hat (für denselben CKM_RSA_PKCS_OAEP), wird es nicht schwierig sein, die Unterstützung für Parameterstrukturen für andere Mechanismen zu implementieren. Wenn also jemand mit einem PKCS # 12-Container arbeiten muss,Dann müssen Sie die Unterstützung für die Struktur CK_PKCS5_PBKD2_PARAMS implementieren.
All dies bezieht sich auf ziemlich komplexe kryptografische Mechanismen.
Aber alles, was mit Hashing, der Überprüfung einer elektronischen Signatur und schließlich der Verschlüsselung zu tun hat, funktioniert hervorragend. Aber zuerst müssen Sie ein Projekt zusammenstellen.
II. Erstellen eines PyKCS11-Wrappers mit GOST-Unterstützung
Es unterscheidet sich nicht vom Erstellen des nativen PkCS11-Wrappers, außer dass Sie den Quellcode hier abrufen müssen .
Befolgen Sie als Nächstes die Anweisungen zum Erstellen und Installieren des PyKCS11-Pakets.
Für das Testen ist ein Token mit russischer Kryptografieunterstützung erforderlich. Hier meinen wir GOST R 34.10-2012 und GOST R 34.11-2012. Dies kann entweder ein Hardware-Token sein, z. B. RuTokenECP-2.0, oder ein Software- oder Cloud-Token.
Sie können ein Software-Token installieren oder mit dem Dienstprogramm cryptoarmpkcs auf ein Cloud-Token zugreifen.
Nach dem Starten des Dienstprogramms müssen Sie zur
Registerkarte "Token erstellen" wechseln : Auf der Registerkarte finden Sie Anweisungen zum Abrufen und Installieren von Token.
III. Testen russischer Algorithmen
Zum Testen können Sie die Skripte verwenden, die sich im Ordner testGost befinden:
- ckm_kuznyechik_cbc.py
- ckm_gostr3411_12_256.py
- ckm_gostr3410_with_gostr3411_12_256.py
- ckm_gostr3410_512.py
Zum Testen wurden die Anfangsdaten sowohl den entsprechenden GOSTs als auch den Empfehlungen von TK-26 entnommen.
Die folgenden Mechanismen werden in diesen Skripten getestet:
1. Generierung von Schlüsselpaaren:
- CKM_GOSTR3410_512_KEY_PAIR_GEN (GOST R 34.10-2012 mit einer Schlüssellänge von 1024 Bit)
- CKM_GOSTR3410_KEY_PAIR_GEN (GOST R 34.10-2012 mit 512-Bit-Schlüssellänge)
2. Bildung und Überprüfung einer elektronischen Signatur:
- CKM_GOSTR3410
- CKM_GOSTR3410_512
- CKM_GOSTR3410_WITH_GOSTR3411_12_256
3. Hashing:
- CKM_GOSTR3411_12_256
4. Verschlüsselung / Entschlüsselung
- CKM_KUZNYECHIK_CBC
Durch das Generieren von Schlüsselpaaren kann der Token-Inhaber einen privaten Schlüssel erhalten, mit dem er beispielsweise eine Zertifikatanforderung signieren kann. Eine Anforderung für ein Zertifikat kann an ein Zertifizierungszentrum gesendet und dort ein Zertifikat ausgestellt werden. Der Eigentümer des Zertifikats kann es in das Token importieren, in dem der private Schlüssel gespeichert ist. Der Token-Besitzer verfügt jetzt über ein persönliches Zertifikat mit einem privaten Schlüssel, mit dem er Dokumente signieren kann.
Wenn er einen speziellen Sicherheitsmodus benötigt, kann er das Dokument mit einem der Algorithmen verschlüsseln, nämlich Magma oder Grasshopper. Wenn das Token selbst diese Mechanismen unterstützt, ist das PyKCS11-Paket natürlich nur ein Vermittler.
Damit ist unsere Geschichte über die Unterstützung von Token mit russischer Kryptographie in Python abgeschlossen.