Я использую пакет Python pkcs11 для доступа к сертификату X.509, хранящемуся на моем Yubikey 5. Доступ к сертификату, открытому и закрытому ключам с помощью pkcs11 Объекты работают хорошо, как подпись и проверка подписи. Однако я не могу понять, почему шифрование с помощью открытого ключа не работает. Вот мой код:
import pkcs11
from pkcs11 import Attribute, ObjectClass, KeyType, util
lib = pkcs11.lib('/usr/lib/x86_64-linux-gnu/pkcs11/onepin-opensc-pkcs11.so')
token = lib.get_token(token_label='PIV Card Holder pin (PIV_II)'
session = token.open(user_pin=pin)
# Getting a private and a public key as pkcs11 Object
private = next(session.get_objects({
Attribute.CLASS: ObjectClass.PRIVATE_KEY,
}))
public = next(session.get_objects({
Attribute.CLASS: ObjectClass.PUBLIC_KEY,
}))
data = 'Hello, world!'
sig = private.sign(data) # Works!
sig_verif = public.verify(data, sig) # Works!
print("Signature is valid? "+str(sig_verif)) # True
# So far, everything above worked fine.
# ----------
# Now, this is the part that does not work
encrypt_data = public.encrypt(data) # Fails!
Последняя строка выше завершается с ошибкой pkcs11.exceptions.FunctionNotSupported . Я провел некоторое исследование, и это объяснение, которое я нашел, похоже, подразумевает, что эта функция (encrypt) не поддерживается библиотечным файлом openSC (* .so), который я использую. Однако мне трудно поверить, учитывая, что функция подписи работает просто отлично.
Просто чтобы убедиться, что я могу использовать этот конкретный открытый ключ вне контекста сеанса, я попробовал следующий код, используя пакет Crypto:
from Crypto.Cipher import PKCS1_OAEP
public_key = RSA.importKey(public[Attribute.VALUE]) # The content of pkcs11 public key as DER
cipher = PKCS1_OAEP.new(public_key)
encr_data = cipher.encrypt(data) # This works!
Итак, похоже, что мой стандартодин открытый ключ позволяет мне шифровать данные. Но почему я не могу сделать это в контексте сеанса токена pkcs11?
Затем я попытался использовать функцию расшифровки объекта pkcs11, чтобы попытаться расшифровать данные, сгенерированные с помощью модуля Crypto, описанного выше:
decrypted = private.decrypt(encr_data) # It fails!
Выше не удалось с pkcs11.exceptions.MechanismInvalid ошибка. Я пытался использовать разные механизмы, но все они привели к одной и той же ошибке. Что интересно - кажется, что объект pkcs11 позволяет мне хотя бы вызвать функцию decrypt , не жалуясь, что она не поддерживается.
Еще одна вещь, которую я должен упомянуть. Я проверил свой сертификат и увидел, что в разделе «Расширение -> Использование ключа сертификата» написано:
Critical
Signing
Key Encipherment
Я прочел разницу между шифрованием ключей и шифрованием данных и узнал, что шифрование ключа используется для шифрования секретного (симметричного) ключа вместо данных. Может ли это быть причиной того, что я не могу использовать функцию encrypt для этого сеанса токена?
Любая обратная связь будет принята с благодарностью!