首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用pkcs11模块加密使用公钥的数据失败

使用pkcs11模块加密使用公钥的数据失败
EN

Stack Overflow用户
提问于 2019-10-27 23:10:49
回答 2查看 3.3K关注 0票数 3

我使用Python的pkcs11包访问存储在我的Yubikey 5上的X.509证书。访问证书时,使用pkcs11对象的公钥和私钥可以正常工作,就像签名和签名验证一样。然而,为了我的生命,我不明白为什么用公钥加密不起作用。这是我的代码:

代码语言:javascript
复制
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包尝试了以下代码:

代码语言:javascript
复制
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模块生成的数据进行解密:

代码语言:javascript
复制
decrypted = private.decrypt(encr_data) # It fails!

由于pkcs11.exceptions.MechanismInvalid错误,上述操作失败。我试着使用不同的机制,但它们都导致了相同的错误。有趣的是-- pkcs11对象似乎允许我至少调用解密函数,而不抱怨它不受支持。

我还要提一件事。我检查了我的证书,发现在扩展的->证书密钥用法中,它说:

代码语言:javascript
复制
Critical
Signing
Key Encipherment

我阅读了密钥加密和数据加密的区别,了解到密钥加密用于加密秘密(对称)密钥而不是数据。难道这就是我不能在这个令牌会话中使用加密函数的原因吗?

如有任何反馈,将不胜感激!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-30 15:12:53

对不起,但我认为这只是API的一个缺点。由于使用公钥加密不需要任何安全性,因此在Yubikey上实现它是没有意义的。在主机上导出公钥值和执行加密要快得多。

公平地说,Yubikey可以很好地实现Ubikey PKCS#11库中的软件功能。如果您真的想要这样做,那么您可以创建一个新的PKCS#11“包装器”库,它确实包含了软件中缺少的功能;可以将Yubikey实现的所有其他命令转发给原始的Yubikey PKCS#11库。

票数 2
EN

Stack Overflow用户

发布于 2019-10-30 19:36:22

在进行了相当广泛的研究并考虑到这个线程的答复之后,我发现在这个令牌会话中无法使用的加密是由于OpenSC API限制造成的。事实上,python 11页面上有一个兼容性表,它显示(纯文本) OpenSC不支持加密、对称密钥生成、密钥包装和其他功能。它完全支持签名/验证,部分支持解密。如果我做了更好的搜索,它会节省我很多时间。

事实上,使用‘pkcs11 11工具’进行硬令牌测试是非常有用的,因为它将显示每个PIV插槽所支持的功能和机制。在我的例子中,我引用它如下:

代码语言:javascript
复制
pkcs11-tool -p $pin -t

并收到以下报告:

代码语言:javascript
复制
Using slot 0 with a present token (0x0)
C_SeedRandom() and C_GenerateRandom():
  seeding (C_SeedRandom) not supported
  seems to be OK
Digests:
  all 4 digest functions seem to work
  MD5: OK
  SHA-1: OK
  RIPEMD160: OK
Signatures (currently only for RSA)
  testing key 0 (PIV AUTH key) 
  all 4 signature functions seem to work
  testing signature mechanisms:
    RSA-X-509: OK
    RSA-PKCS: OK
    SHA1-RSA-PKCS: OK
    MD5-RSA-PKCS: OK
    RIPEMD160-RSA-PKCS: OK
    SHA256-RSA-PKCS: OK
  testing key 1 (2048 bits, label=SIGN key) with 1 signature mechanism
    RSA-X-509: OK
  testing key 2 (2048 bits, label=KEY MAN key) with 1 signature mechanism -- can't be used to sign/verify, skipping
Verify (currently only for RSA)
  testing key 0 (PIV AUTH key)
    RSA-X-509: OK
    RSA-PKCS: OK
    SHA1-RSA-PKCS: OK
    MD5-RSA-PKCS: OK
    RIPEMD160-RSA-PKCS: OK
  testing key 1 (SIGN key) with 1 mechanism
    RSA-X-509: OK
  testing key 2 (KEY MAN key) with 1 mechanism -- can't be used to sign/verify, skipping
Unwrap: not implemented
Decryption (currently only for RSA)
  testing key 0 (PIV AUTH key) 
    RSA-X-509: OK
    RSA-PKCS: OK
  testing key 1 (SIGN key) 
    RSA-X-509: OK
    RSA-PKCS: OK
  testing key 2 (KEY MAN key) 
    RSA-X-509: OK
    RSA-PKCS: OK
No errors

从这里,我们可以看到,解密是支持所有三个占用的时隙,但只有RSA-X-509和RSA-PKCS机制(没有OAEP)。

现在,我正在考虑融合pkcs11 11工具和openssl功能来进行数据加密。我还没有弄清楚这种流的所有复杂之处,但我想到的是这类

  1. (pkcs11 11-工具)从所需的PIV插槽导出证书
  2. (openssl)创建对称密钥(例如AES)
  3. (openssl)用这个秘密密钥加密数据
  4. (openssl)使用步骤1中的证书加密密钥
  5. 将对称加密数据和非对称加密密钥发送给收件人。
  6. (pkcs11 11-tool)解密安全令牌上的密钥
  7. (openssl)使用解密的秘密密钥来解密实际数据

看起来,我应该能够在Linux中使用pkcs11 11工具和openssl实用程序,或者在Python中使用pkcs11和OpenSSL库来实现这样的解决方案。后者似乎更可取,如果我决定以后通过GUI完成它。这一切看起来都很低,所以我想知道是否有一种更简单的加密/解密数据的方法。我知道PGP将加密的数据融合在一起,并将密钥封装到一个文件中,因此最终用户只需在其端执行一个命令。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58584152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档