从单个python线程中,如下所示,我收到错误“请在任何插槽中插入令牌”,它似乎看不到我的令牌。我将代码更改为不从多处理线程内部运行并且它可以正常工作。为了将PyKCS11库从等式中取出,我还使用ctypes进行了测试并包装了opensc中实现的标准pkcs11函数,除了从python Thread运行时,我仍遇到同样的问题。会导致这种情况的原因是什么?
在python中使用pkcs11线程失败:
from PyKCS11 import LowLevel
import sys
from multiprocessing import Thread
class MyThread(Thread):
def run(self):
lib = "/usr/local/lib/opensc-pkcs11.so" # place here your PKCS#11 library
pin = "12345678" # place here the pin of your token
a = LowLevel.CPKCS11Lib()
info = LowLevel.CK_INFO()
slotList = LowLevel.ckintlist()
loadRes = a.Load(lib, 1)
print "Load of library '%s' : %s " % (lib, str(loadRes) )
if not loadRes:
sys.exit(1)
print "C_GetInfo: rv=" , hex(a.C_GetInfo(info))
print "Library manufacturerID: ", info.GetManufacturerID()
# listing only slots with a token inside.
rv = a.C_GetSlotList(1, slotList)
if (rv != LowLevel.CKR_OK):
sys.exit(1)
if len(slotList) == 0:
print "Please insert a token in any slot"
sys.exit(1)
mythread = MyThread()
mythread.start()
mythread.join()
在线程之外使用pkcs11:
from PyKCS11 import LowLevel
import sys
def run(self):
lib = "/usr/local/lib/opensc-pkcs11.so" # place here your PKCS#11 library
pin = "12345678" # place here the pin of your token
a = LowLevel.CPKCS11Lib()
info = LowLevel.CK_INFO()
slotList = LowLevel.ckintlist()
loadRes = a.Load(lib, 1)
print "Load of library '%s' : %s " % (lib, str(loadRes) )
if not loadRes:
sys.exit(1)
print "C_GetInfo: rv=" , hex(a.C_GetInfo(info))
print "Library manufacturerID: ", info.GetManufacturerID()
# listing only slots with a token inside.
rv = a.C_GetSlotList(1, slotList)
if (rv != LowLevel.CKR_OK):
sys.exit(1)
if len(slotList) == 0:
print "Please insert a token in any slot"
sys.exit(1)
run()
测试环境:
操作系统:OSX Yosemite
pkcs11中间件:opensc
答案 0 :(得分:0)
有关多线程和PKCS#11库的更多信息,请参阅PKCS#11 v2.20规范的第6.6.2节:
6.6.2应用程序和线程
某些应用程序将以多线程方式访问Cryptoki库 时尚。 Cryptoki使应用程序能够提供信息 图书馆,以便他们可以给予适当的支持 多线程。特别是,当应用程序初始化a时 Cryptoki库调用C_Initialize,它可以指定其中一个 库的四种可能的多线程行为:
- 应用程序可以指定它不会从多个线程同时访问库,因此库需要 不用担心为了执行任何类型的锁定 线程安全。
- 应用程序可以指定它将从多个线程同时访问库,并且库必须能够 使用本机操作系统同步原语来确保 适当的线程安全行为。
- 应用程序可以指定它将从多个线程同时访问库,并且库必须使用一组 应用程序提供的同步原语以确保正确 线程安全的行为。
- 应用程序可以指定它将从多个线程同时访问库,并且库必须使用其中一个 本机操作系统同步原语或一组 应用程序提供的同步原语以确保正确 线程安全的行为。
醇>
IMO是多线程应用程序中最常用的类型是第二种类型。要激活它,您需要将CKF_OS_LOCKING_OK
标记传递给C_Initialize
函数。以下代码显示了如何使用Pkcs11Interop库在C#中实现此目的:
Pkcs11 pkcs11 = new Pkcs11(libraryPath);
CK_C_INITIALIZE_ARGS initArgs = new CK_C_INITIALIZE_ARGS();
initArgs.Flags = CKF.CKF_OS_LOCKING_OK;
CKR rv = pkcs11.C_Initialize(initArgs);
if ((rv != CKR.CKR_OK) && (rv != CKR.CKR_CRYPTOKI_ALREADY_INITIALIZED))
throw new Pkcs11Exception("C_Initialize", rv);
我相信你需要在Python中使用类似的代码。只是在这里猜测,但也许你需要将一些参数传递给LowLevel.CPKCS11Lib()
?