首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用带有python的智能卡发出TLS请求?

如何使用带有python的智能卡发出TLS请求?
EN

Stack Overflow用户
提问于 2017-07-29 06:12:44
回答 3查看 3.8K关注 0票数 7

我尝试使用python库“请求”与受智能卡保护的网站进行通信。这意味着SSL中的强身份验证:您必须给客户端证书(证书和私钥)。

由于我使用智能卡,我不能读取私钥(只有模数),这是一个正常的保护。我可以用python库PyKCS11读取智能卡:一旦给出密码,所有证书、公钥和私钥模数。

如何将请求和PyKCS11混合使用?

如何使用智能卡中的客户端证书发出SSL请求?

编辑2017/08/04

在我的Mac上:

  • brew安装openssl
  • brew安装操作系统
  • brew安装engine_pkcs11
  • openssl
    • 引擎动态SO_PATH:/usr/local/Cellar/engine_pkcs11/0.1.8/lib/engines/engine_pkcs11.so -pre ID:pkcs11 11 -pre LIST_ADD:1 -pre LOAD -pre模块_PATH:/usr/local/lib/(我的特定Pkcs11库).dylib
      • 加载:( pkcs11 ) pkcs11引擎

代码语言:javascript
运行
复制
- s\_client -engine pkcs11 -key '(slot):(id)' -keyform engine -cert 'pem.cer' -connect (host):443 -state -debug  
    - SSL handshake ok

我现在的问题是,pyOpenSSl在API中没有选择引擎的函数(比如pkcs11)。所以我被阻止了。我不能用蟒蛇。

EN

回答 3

Stack Overflow用户

发布于 2020-02-27 00:28:59

我也有类似的问题,除了我在窗口,需要使用"capi“引擎来处理智能卡客户证书。我有一个使用cffi和pyopenssl请求的工作代码,我希望将它更改为支持pkcs11应该不会太困难。

代码语言:javascript
运行
复制
import os
import ssl
import sys

import cffi
import requests

pyopenssl = requests.packages.urllib3.contrib.pyopenssl
pyopenssl.inject_into_urllib3()

# I use anaconda and these paths are valid for me, change as required
libcryptopath = os.path.join(sys.prefix, "Library", "bin", "libcrypto-1_1-x64.dll")
libsslpath = os.path.join(sys.prefix, "Library", "bin", "libssl-1_1-x64.dll")
capipath = os.path.join(sys.prefix, "Library", "lib", "engines-1_1", "capi.dll")

ffi = cffi.FFI()
ffi.cdef(
    "void *ENGINE_by_id(const char *id);"
    "int ENGINE_ctrl_cmd_string(void *e, const char *cmd_name, const char *arg, int cmd_optional);"
    "int ENGINE_init(void *e);"
    "int SSL_CTX_set_client_cert_engine(void *ctx, void *e);"
)

try:
    libcrypto, libssl, engine
except NameError:
    libcrypto = ffi.dlopen(libcryptopath)
    libssl = ffi.dlopen(libsslpath)
    engine = libcrypto.ENGINE_by_id(b"dynamic")
    libcrypto.ENGINE_ctrl_cmd_string(engine, b"SO_PATH", capipath.encode(), 0)
    libcrypto.ENGINE_ctrl_cmd_string(engine, b"LOAD", ffi.NULL, 0)
    libcrypto.ENGINE_init(engine)


class PyOpenSSLContextCAPI(pyopenssl.PyOpenSSLContext):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        libssl.SSL_CTX_set_client_cert_engine(self._ctx._context, engine)


# https://lukasa.co.uk/2017/02/Configuring_TLS_With_Requests/
class HTTPAdapterCAPI(requests.adapters.HTTPAdapter):
    def init_poolmanager(self, *args, **kwargs):
        context = PyOpenSSLContextCAPI(ssl.PROTOCOL_TLS)
        kwargs['ssl_context'] = context
        return super().init_poolmanager(*args, **kwargs)


class SessionCAPI(requests.Session):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.mount("https://", HTTPAdapterCAPI())


if __name__ == '__main__':
    s = SessionCAPI()
    r = s.get("https://example.com")
    print(r.text)
票数 2
EN

Stack Overflow用户

发布于 2017-07-29 08:38:13

我试着用:

票数 0
EN

Stack Overflow用户

发布于 2018-08-21 15:17:04

它与M2Crypto一起工作:

代码语言:javascript
运行
复制
def InitPKCS11Engine(id, dllPath):
    Engine.load_dynamic()
    e = Engine.Engine('dynamic')
    e.ctrl_cmd_string('SO_PATH', dllPath)
    e.ctrl_cmd_string('ID', id)
    e.ctrl_cmd_string('LIST_ADD', '1')
    e.ctrl_cmd_string('LOAD', None)
    return e

之后,您可以添加特定的pkcs11库并添加引脚。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45385964

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档