智能卡PKCS11 AES密钥生成失败

2024-06-18 18:50:33 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在ACOS5-64智能卡和OMNIKEY 3121读卡器上创建aes256密钥,使用python中的PKCS11(使用PyKCS11库)。到目前为止,所有的“标准”操作似乎都适用于非对称加密。我运行了大量的代码示例和pkcs11工具命令,用于初始化令牌、设置/更改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')

但是,我在运行它时遇到一个错误:

^{pr2}$

问题是,如果我将CKA_令牌行切换为False,那么它就“起作用了”。当然,通过将其设置为false,它使密钥成为会话对象而不是令牌对象(即,在我注销后,密钥被擦除)。将pkcs11工具与--list objects一起使用时,键不在那里。我可以使用ACSCMU(令牌管理的GUI工具),我可以在“Secret key Manager”中创建AES密钥,它确实创建了一个持久密钥。但是我不知道ACSCMU是如何使它持久化的(它可能根本没有使用PKCS11)。在

如果非要我猜问题的话,我想这和会议有关。如果CKA_TOKEN=True无效,那么似乎该令牌实际上没有处于RW模式(如第9行的CKF_RW_会话所建议的那样)。到目前为止,我不知道还有什么可以尝试或者如何调试这个。在


Tags: 工具keytruesessionpin密钥aesrw
2条回答

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

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

经过大量的例子,我自己发现了这个问题:如果要创建一个持久(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工具查看新对象:

^{pr2}$

相关问题 更多 >