【问题标题】:Smartcard PKCS11 AES Key Gen Failure智能卡 PKCS11 AES 密钥生成失败
【发布时间】:2015-07-18 08:58:54
【问题描述】:

我正在尝试使用 Python 中的 PKCS11(使用 PyKCS11 库)在 ACOS5-64 智能卡和 OMNIKEY 3121 读卡器上创建 AES 256 密钥。到目前为止,所有“标准”操作似乎都适用于非对称加密。我已经运行了大量的代码示例和 pkcs11-tool 命令,用于初始化令牌、设置/更改 PIN、创建 RSA 密钥对等。因此,驱动程序都可以正常工作(pcscd、CCID、PKCS11 中间件)。

以下代码导致问题:

from PyKCS11 import *
import getpass
libacospkcs = '/usr/lib/libacospkcs11.so'

def createTokenAES256(lbl):
   pkcs11 = PyKCS11Lib()
   pkcs11.load(libacospkcs)
   theOnlySlot = pkcs11.getSlotList()[0]
   session = pkcs11.openSession(theOnlySlot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
   PIN = getpass.getpass('Enter User PIN to login:')
   session.login(PIN)

   t = pkcs11.getTokenInfo(theOnlySlot)
   print t.label
   print t.model
   print t.serialNumber

   template = (
      (CKA_CLASS, CKO_SECRET_KEY),
      (CKA_KEY_TYPE, CKK_AES),
      (CKA_VALUE_LEN, 32),
      (CKA_LABEL, "A"),
      (CKA_PRIVATE, True),
      (CKA_SENSITIVE, True),
      (CKA_ENCRYPT, True),
      (CKA_DECRYPT, True),
      (CKA_TOKEN, True),
      (CKA_WRAP, True),
      (CKA_UNWRAP, True),
      (CKA_EXTRACTABLE, False))
   ckattr = session._template2ckattrlist(template)
   m = LowLevel.CK_MECHANISM()
   m.mechanism = LowLevel.CKM_AES_KEY_GEN

   key = LowLevel.CK_OBJECT_HANDLE()
   returnValue = pkcs11.lib.C_GenerateKey( session.session, m, ckattr, key)

   if returnValue != CKR_OK:
      raise PyKCS11Error(returnValue)

# Now run the method to create the key
createTokenAES256('TestAESKey')

但是,运行时出现错误:

~/projects/smartcard $ python testpkcs11again.py 
Enter User PIN to login:
Token #A                        
ACOS5-64        
30A740C8704A
Traceback (most recent call last):
  File "testcreateaes.py", line 43, in <module>
    createTokenAES256('TestAESKey')
  File "testcreateaes.py", line 40, in createTokenAES256
    raise PyKCS11Error(returnValue)
PyKCS11.PyKCS11Error: CKR_ATTRIBUTE_VALUE_INVALID (0x00000013)

问题是,如果我将 CKA_TOKEN 行切换为 False,那么它“有效”。当然,通过将其设置为 false,它使密钥成为会话对象而不是令牌对象(即,在我注销后,密钥被擦除)。将 pkcs11-tool 与 --list-objects 一起使用,密钥不存在。我可以使用 ACSCMU​​(令牌管理员的 GUI 工具),我可以在“秘密密钥管理器”中创建一个 AES 密钥,它确实创建了一个持久密钥。但我无法看到 ACSCMU​​ 正在做什么来使其持久化(它可能根本没有使用 PKCS11)。

如果我必须猜测问题,我猜它与会话有关。如果 CKA_TOKEN=True 无效,那么似乎令牌实际上并不处于 RW 模式(如第 9 行中的 CKF_RW_SESSION 所建议的那样)。到目前为止,我不确定还可以尝试什么或如何调试它。

【问题讨论】:

    标签: python aes smartcard pkcs#11


    【解决方案1】:

    经过大量挖掘大量示例后,我自己想通了:如果您要创建持久性 (CKA_TOKEN=True) 对象,CKA_ID 是必需的属性。不知道我应该如何知道这一点(从未在任何文档中看到过),但确实在我添加之后它工作得很好。

    如果您正确设置了驱动程序,此代码应该可以工作:

    from PyKCS11 import *
    import getpass
    libacospkcs = '/usr/lib/libacospkcs11.so'
    
    def createTokenAES256(label):
       pkcs11 = PyKCS11Lib()
       pkcs11.load(libacospkcs)
       theOnlySlot = pkcs11.getSlotList()[0]
       session = pkcs11.openSession(theOnlySlot, CKF_SERIAL_SESSION | CKF_RW_SESSION)
       PIN = getpass.getpass('Enter User PIN to login:')
       session.login(PIN)
    
       print pkcs11.getTokenInfo(theOnlySlot)
    
       template = (
          (CKA_CLASS, CKO_SECRET_KEY),
          (CKA_KEY_TYPE, CKK_AES),
          (CKA_VALUE_LEN, 32),
          (CKA_LABEL, label),
          (CKA_ID, "1244"),
          (CKA_PRIVATE, True),
          (CKA_SENSITIVE, True),
          (CKA_ENCRYPT, True),
          (CKA_DECRYPT, True),
          (CKA_TOKEN, True),
          (CKA_WRAP, True),
          (CKA_UNWRAP, True),
          (CKA_EXTRACTABLE, False))
       ckattr = session._template2ckattrlist(template)
       m = LowLevel.CK_MECHANISM()
       m.mechanism = LowLevel.CKM_AES_KEY_GEN
    
       key = LowLevel.CK_OBJECT_HANDLE()
       returnValue = pkcs11.lib.C_GenerateKey( session.session, m, ckattr, key)
    
       if returnValue != CKR_OK:
          raise PyKCS11Error(returnValue)
    
    # Now execute the above to create AES256 key
    createTokenAES256('TestKey')
    

    在此之后,我可以注销卡并使用 pkcs11-tool 查看新对象:

    $ pkcs11-tool --module=/usr/lib/libacospkcs11.so --list-objects
    Using slot 0 with a present token (0x0)
    Secret Key Object; unknown key algorithm 31
      label:      TestKey
      ID:         31323434
      Usage:      encrypt, decrypt, wrap, unwrap, derive
    

    【讨论】:

    • @Alan 你是如何从 pkcs11 获得 aes 密钥的?我无法从 acos64 获取。它给出了空值。我可以从 acscmu 创建广告,但无法获取和加密。
    【解决方案2】:

    IMO 对此您无能为力,只能联系libacospkcs11.so 的制作人并寻求解释。您很可能会被引导到文档,该文档将声明对称密钥只能作为会话对象创建,并且使用此类密钥的所有操作都在 SW(而不是卡中)中执行 - 这是大多数人的常见做法商用卡和中间件套件。

    顺便说一句,您也可以尝试为CKM_AES_KEY_GEN 机制(以及您计划使用的其他AES 机制)调用C_GetMechanismInfo,并检查响应中是否设置了CKF_HW 标志。此标志指示该机制是由设备执行还是在软件中执行。

    【讨论】:

      猜你喜欢
      • 2012-06-05
      • 2013-06-23
      • 2020-08-27
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-31
      • 1970-01-01
      相关资源
      最近更新 更多