我试图在ACOS5 5-64智能卡和OMNIKEY 3121读卡器上创建一个AES 256密钥,在python中使用PKCS11 (使用PyKCS11库)。到目前为止,所有的“标准”操作似乎都适用于非对称密码。我运行了大量的代码示例和PKCS11 11工具命令,以初始化令牌、设置/更改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 11工具和-列表对象,键就不存在了。我可以使用ACSCMU (用于令牌管理的GUI工具),我可以在“秘密密钥管理器”中创建一个AES密钥,并且它确实创建了一个持久密钥。但是,我无法看到ACSCMU正在做什么来使它持久(它可能根本没有使用PKCS11 )。
如果我必须猜出问题,我猜这与会议有关。如果CKA_TOKEN=True无效,那么令牌似乎实际上并不处于RW模式(如CKF_RW_SESSION在第9行中所建议的那样)。到目前为止,我还不确定还需要尝试什么或者如何调试它。
发布于 2015-05-07 21:11:19
在深入研究了大量示例之后,我自己解决了这个问题:如果要创建一个持久性(CKA_TOKEN=True)对象,那么CKA_TOKEN=True是一个必需的属性。我不知道我是怎么知道这一点的(在任何文档中都没有见过),但实际上,在我添加了它之后,它工作得非常好。
如果您正确地安装了驱动程序,则此代码应该可以工作:
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 11-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发布于 2015-05-07 21:03:38
海事组织对此你无能为力,只能联系libacospkcs11.so的制片人并要求解释。您很可能会被引导到文档中,该文档将声明对称密钥只能作为会话对象创建,所有具有此类密钥的操作都在SW (而不是在卡片中)执行--这是大多数商业上可用的卡和中间件套件中的常见做法。
顺便说一句,您还可以尝试为C_GetMechanismInfo机制调用CKM_AES_KEY_GEN机制(以及您计划使用的其他CKM_AES_KEY_GEN机制),并检查响应中是否设置了CKF_HW标志。此标志指示该机制是由设备执行还是在软件中执行。
https://stackoverflow.com/questions/30106966
复制相似问题