【问题标题】:pkcs11 in python Threadpython线程中的pkcs11
【发布时间】:2016-08-01 20:23:17
【问题描述】:

在单个 python 线程中,如下所示,我收到错误“请在任何插槽中插入令牌”,它似乎看不到我的令牌。我将代码更改为不在多处理线程内部运行,它可以工作。为了将 PyKCS11 库排除在等式之外,我还通过使用 ctypes 并包装了在 opensc 中实现的标准 pkcs11 函数进行了测试,除了从 python 线程运行时,我仍然遇到相同的问题。这是什么原因造成的?

在 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

【问题讨论】:

    标签: multiprocessing ctypes smartcard pkcs#11 opensc


    【解决方案1】:

    有关多线程和 PKCS#11 库的更多信息可以在 PKCS#11 v2.20 规范的第 6.6.2 章中找到:

    6.6.2 应用程序和线程

    一些应用程序将以多线程访问 Cryptoki 库 时尚。 Cryptoki 使应用程序能够向 图书馆,以便他们可以提供适当的支持 多线程。特别是,当应用程序初始化一个 Cryptoki 库调用 C_Initialize,它可以指定以下之一 库的四种可能的多线程行为:

    1. 应用程序可以指定它不会同时从多个线程访问库,因此库需要 不用担心为了执行任何类型的锁定 线程安全。
    2. 应用程序可以指定它将从多个线程同时访问库,并且库必须能够 使用本机操作系统同步原语来确保 正确的线程安全行为。
    3. 应用程序可以指定它将从多个线程同时访问库,并且库必须使用一组 应用程序提供的同步原语,以确保正确 线程安全的行为。
    4. 应用程序可以指定它将同时从多个线程访问库,并且库必须使用 本机操作系统同步原语或一组 应用程序提供的同步原语,以确保正确 线程安全的行为。

    IMO 多线程应用程序中最常用的类型是第 2 类。要激活它,您需要将CKF_OS_LOCKING_OK 标志传递给C_Initialize 函数。以下代码展示了如何在 C# 中使用 Pkcs11Interop 库实现这一点:

    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()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多