【发布时间】:2020-02-23 07:39:43
【问题描述】:
我正在使用 Python 的 pkcs11 包来访问存储在我的 Yubikey 5 上的 X.509 证书。使用 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 错误而失败。我做了一些研究,我发现的解释似乎暗示我正在使用的 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 函数而不会抱怨它不受支持。
我还要提一件事。我检查了我的证书,在 Extension -> Certificate Key Usage 下看到,它说:
Critical
Signing
Key Encipherment
我阅读了 key encipherment 和 data encipherment 之间的区别,并了解到 key encipherment 用于加密秘密(对称)密钥而不是数据。这可能是我无法在此令牌会话中使用 encrypt 功能的原因吗?
任何反馈将不胜感激!
【问题讨论】:
-
令牌中的每个对象都具有某些属性,这些属性定义了对象的用途。您应该查看的属性是
Encrypt和Decrypt。是否为您尝试加密操作的公钥启用了这些功能? -
@always_a_rookie_to_learn:我检查了 ''public[Attribute.ENCRYPT]'' 并且它返回 True,所以我猜它在这个对象中启用了。
标签: python smartcard public-key-encryption pkcs#11 opensc