【问题标题】:Need help using M2Crypto.Engine to access USB Token需要帮助使用 M2Crypto.Engine 访问 USB 令牌
【发布时间】:2010-02-03 20:28:11
【问题描述】:

我正在使用 M2Crypto-0.20.2。我想使用 OpenSC 项目中的 engine_pkcs11 和 Aladdin PKI 客户端进行基于令牌的身份验证,通过 ssl 进行 xmlrpc 调用。

from M2Crypto import Engine

Engine.load_dynamic()
dynamic = Engine.Engine('dynamic')
# Load the engine_pkcs from the OpenSC project
dynamic.ctrl_cmd_string("SO_PATH", "/usr/local/ssl/lib/engines/engine_pkcs11.so")
Engine.cleanup()

Engine.load_dynamic()
# Load the Aladdin PKI Client
aladdin = Engine.Engine('dynamic')
aladdin.ctrl_cmd_string("SO_PATH", "/usr/lib/libeTPkcs11.so")

key = aladdin.load_private_key("PIN","password")

这是我收到的错误:

key = pkcs.load_private_key("PIN","eT0ken")
File "/usr/local/lib/python2.4/site-packages/M2Crypto/Engine.py", line 70, in load_private_key
    return self._engine_load_key(m2.engine_load_private_key, name, pin)
File "/usr/local/lib/python2.4/site-packages/M2Crypto/Engine.py", line 60, in _engine_load_key
    raise EngineError(Err.get_error())
M2Crypto.Engine.EngineError: 23730:error:26096075:engine routines:ENGINE_load_private_key:not initialised:eng_pkey.c:112:

对于load_private_key(),第一个参数应该传递什么? M2Crypto 文档没有解释它。

我在加载引擎时没有收到任何错误,但我不确定我是否正确加载它们。似乎引擎 ID 必须是特定名称,但我在任何地方都找不到该列表。 'dynamic' 为我工作。

任何帮助将不胜感激!

【问题讨论】:

    标签: python m2crypto


    【解决方案1】:

    找到了!!!!

    是的,正是我来自的地方。

    所以,实际上 ENGINE_init() 并没有在 M2Crypto.Engine 中实现。所以,只有一个解决方案:打补丁!!! (非常小......)所以我创建了一个新的 Engine 方法(在 Engine.py 中)

    def engine_initz(self):
            """Return engine name"""
            return m2.engine_initz(self._ptr)
    

    为什么是 engine_initz ?因为 engine_init 已经在 SWIG/_engine.i 中定义了,:

    void engine_init(PyObject *engine_err) {
        Py_INCREF(engine_err);
        _engine_err = engine_err;
    }
    

    我真的不知道做了什么,所以我更喜欢创建一个新的......所以我刚刚将以下内容添加到 SWIG/_engine.i:

    %rename(engine_initz) ENGINE_init;
    extern int ENGINE_init(ENGINE *);
    

    然后重新编译__m2crypto.so,现在只需在启动私钥之前添加一个“pkcs11.engine_initz()”,它就可以工作了.....

    【讨论】:

    • 干得好!我按照您的说明修补了 M2Crypto,并且也能够克服初始化错误。谢谢。
    • 干得好!你能在 M2Crypto 上提交一个错误吗?另外,您能否提一下在什么时候需要调用ENGINE_init()
    • 我将当前的 m2.engine_init 更改为 engine_init_error,暴露了 m2.engine_init 和 engine_finish 并在 Engine 类中添加了 init 和 finish 方法。已签入 M2Crypto 主干,请在我发布下一个版本之前进行测试。
    【解决方案2】:

    我不知道当前 M2Crypto 中的 engine_init 代码应该做什么以及为什么。使用以下 M2Crypto 补丁将 ENGINE_init() 公开为 engine_init2 有助于:

    Index: SWIG/_engine.i
    ===================================================================
    --- SWIG/_engine.i  (revision 719)
    +++ SWIG/_engine.i  (working copy)
    @@ -44,6 +44,9 @@
     %rename(engine_free) ENGINE_free;
     extern int ENGINE_free(ENGINE *);
    
    +%rename(engine_init2) ENGINE_init;
    +extern int ENGINE_init(ENGINE *);
    +
     /*
      * Engine id/name functions
      */
    

    在此之后,下面的代码让我更进一步(但 urllib 目前并不完全适合我):

    import sys, os, time, cgi, urllib, urlparse
    from M2Crypto import m2urllib2 as urllib2
    from M2Crypto import m2, SSL, Engine
    
    # load dynamic engine
    e = Engine.load_dynamic_engine("pkcs11", "/Users/martin/prefix/lib/engines/engine_pkcs11.so")
    pk = Engine.Engine("pkcs11")
    pk.ctrl_cmd_string("MODULE_PATH", "/Library/OpenSC/lib/opensc-pkcs11.so")
    
    m2.engine_init2(m2.engine_by_id("pkcs11")) # This makes the trick
    
    cert = e.load_certificate("slot_01-id_01")
    key = e.load_private_key("slot_01-id_01", sys.argv[1])
    
    ctx = SSL.Context("sslv23")
    ctx.set_cipher_list("HIGH:!aNULL:!eNULL:@STRENGTH")
    ctx.set_session_id_ctx("foobar")
    m2.ssl_ctx_use_x509(ctx.ctx, cert.x509)
    m2.ssl_ctx_use_pkey_privkey(ctx.ctx, key.pkey)
    
    opener = urllib2.build_opener(ctx)
    urllib2.install_opener(opener)
    

    【讨论】:

      【解决方案3】:

      看看pastebin link Becky 提供的内容,我相信它在新 API 中会转化为类似这样的内容:

      from M2Crypto import Engine, m2
      
      dynamic = Engine.load_dynamic_engine("pkcs11", "/Users/martin/prefix/lib/engines/engine_pkcs11.so")
      
      pkcs11 = Engine.Engine("pkcs11")
      
      pkcs11.ctrl_cmd_string("MODULE_PATH", "/Library/OpenSC/lib/opensc-pkcs11.so")
      
      r = pkcs11.ctrl_cmd_string("PIN", sys.argv[1])
      
      key = pkcs11.load_private_key("id_01")
      

      所以我敢打赌,如果你用“/usr/local/ssl/lib/engines/engine_pkcs11.so”和“/Library/OpenSC”替换“/Users/martin/prefix/lib/engines/engine_pkcs11.so” /lib/opensc-pkcs11.so" 和 "/usr/lib/libeTPkcs11.so" 你可以让它与阿拉丁一起工作。

      【讨论】:

        【解决方案4】:

        这正是我尝试过的代码。但它以以下错误结束:

        Traceback (most recent call last):
          File "prog9.py", line 13, in <module>
            key = pkcs11.load_private_key("id_45")
          File "/usr/lib/pymodules/python2.5/M2Crypto/Engine.py", line 70, in load_private_key
            return self._engine_load_key(m2.engine_load_private_key, name, pin)
          File "/usr/lib/pymodules/python2.5/M2Crypto/Engine.py", line 60, in _engine_load_key
            raise EngineError(Err.get_error())
        M2Crypto.Engine.EngineError: 11814:error:26096075:engine outines:ENGINE_load_private_key:not initialised:eng_pkey.c:112:
        

        我使用的是 OpenSC PKCS11 库,而不是阿拉丁库。但我认为问题还没有解决。

        【讨论】:

          【解决方案5】:

          我尝试了 Heikki 建议的代码(减去一行)并得到与 Erlo 相同的错误。对于 load_private_key(),我怎么知道要为参数输入什么?

          dynamic = Engine.load_dynamic_engine("pkcs11", "/usr/local/ssl/lib/engines/engine_pkcs11.so")
          #  m2.engine_free(dynamic) this line gave me an error TypeError: in method 'engine_free', argument 1 of type 'ENGINE *'
          
          pkcs11 = Engine.Engine("pkcs11")
          pkcs11.ctrl_cmd_string("MODULE_PATH", "/usr/lib/libeTPkcs11.so")
          
          r = pkcs11.ctrl_cmd_string("PIN", "password")
          
          key = pkcs11.load_private_key("id_01")
          

          【讨论】:

            【解决方案6】:

            我认为问题不在于“load_private_key()”。就像“MODULE_PATH”定义和 load_private_key() 调用之间缺少某些东西。如果你用错误的路径替换“/usr/lib/libeTPkcs11.so”会发生什么?就我而言,我没有与此相关的错误。

            我已经在前台以高调试级别运行“pcscd”,在 python 执行期间没有调用智能卡...所以,我不明白出了什么问题...

            “openssl”中的等效项是使用“-pre”命令。 “-pre”(与“-post”相反)是加载前发送到引擎的命令。也许我们需要在所有“ctrl_cmd_string”调用之后调用一个“加载”引擎的方法?? ...

            迷路了:-/

            【讨论】:

            • 我也迷路了 :) 啊,是的,如果我输入了错误的路径,我仍然会收到相同的“未初始化”错误。你知道什么时候使用 load_dynamic_engine() 和 load_dynamic() 吗?我发布链接的旧示例代码在 ctrl_cmd_strings() 之后有一个 m2.engine_init()。我还没有找到任何与之等效的东西。如果我学到任何东西,我会及时通知你。
            • 我认为在发送 pin 之前,需要初始化引擎,而这并没有发生。openssl 引擎文档讨论了结构和功能引用。要使用引擎功能,您需要通过调用 ENGINE_init() 函数获得的功能引用。我不知道这如何转化为 python/m2crypto 世界。
            • 请查看 Engine.py 和 _engine.i 文件。 m2.engine_init() 只是设置 EngineError 异常类。当您在新 API 中导入 Engine 时,它​​会自动发生。
            猜你喜欢
            • 1970-01-01
            • 2022-07-08
            • 1970-01-01
            • 2021-09-21
            • 2022-01-03
            • 2016-08-18
            • 2016-07-14
            • 2021-07-28
            • 1970-01-01
            相关资源
            最近更新 更多