如何使用智能卡和 python 发出 TLS 请求?

2024-04-12

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

由于我使用的是智能卡,因此我无法读取普通保护的私钥(只能读取模数)。我可以使用 python 库 PyKCS11 读取智能卡:一旦给出 pin 码,所有证书、公钥和私钥模数。

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

编辑2017/08/04

在我的 Mac 上:

  • 酿造安装openssl
  • 酿造安装opensc
  • 酿造安装engine_pkcs11
  • openssl
    • engine dynamic -pre SO_PATH:/usr/local/Cellar/engine_pkcs11/0.1.8/lib/engines/engine_pkcs11.so -pre ID:pkcs11 -pre LIST_ADD:1 -pre LOAD -pre MODULE_PATH:/usr/local/lib/(my specific Pkcs11 lib).dylib
      • 已加载:(pkcs11) pkcs11 引擎
    • s_client -engine pkcs11 -key '(slot):(id)' -keyform engine -cert 'pem.cer' -connect (host):443 -state -debug
      • SSL 握手正常

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


我遇到了类似的问题,除了我在 Windows 上并且需要使用“capi”引擎来处理智能卡客户端证书。我有一个使用 cffi 的工作代码和使用 pyopenssl 的请求,我希望更改它以支持 pkcs11 应该不会太困难。

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)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用智能卡和 python 发出 TLS 请求? 的相关文章

随机推荐

  • Honeycomb Android 模拟器太慢了 - 在正式发布之前它会变得可以管理吗? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • Apache 升级后,simplesaml 出现 403 禁止错误

    我的 simplesaml 工作得很好 直到我在 Ubuntu 上将 Apache 升级到 2 4 6 我收到的错误 Forbidden You don t have permission to access simplesaml on t
  • 在 Log4Net XML 配置中,优先级与级别相同吗?

    我继承了一些在其 xml 配置中使用根下的优先级元素的代码 这就像下面的例子一样http serialized com log4net for noobs http iserialized com log4net for noobs 这表明
  • Ctrl+L 不会清除 Python3.3 终端

    我在 VirtualBox 上的 Ubuntu 12 04 x86 上安装了 Python3 3 来源 configure prefix opt python3 3 make sudo make install 我可以成功启动 python
  • 如何在 JavaScript 中动态构建 JSON?

    var myJSON list1 1 2 list2 a b list3 key1 value1 key2 value2 not a list 11 如何在 JavaScript 中动态构建此 JSON 结构 谷歌告诉我使用一些推送命令 但
  • 将 git 的自动完成功能扩展到管道命令

    作为后续这个问题 https stackoverflow com questions 26752567 is it better to use git branch f or git update ref to fast forware e
  • Firefox 中的 jQuery 扩展

    我正在创建一个 Firefox 扩展 我将 jquery 包含在 xul 文件中 接下来是一些使用 jquery 的其他文件 但在这里我遇到了一些错误 例如
  • Google Developer Console 的凭证方权限

    I got an problem after i create and APIs on Google Developer Console and enable the GCM service but i want to add an ser
  • ES6 中的类声明和类表达式

    我不清楚类表达式和类声明 请帮助我理解它们之间的区别 Thanks 这相对简单 在 类表达式 中 类对象NamedFoo被分配给一个名为的变量Foo 像这样 var Foo class NamedFoo constructor whoIsT
  • 动态创建事件网格主题和订阅,而无需通过编码访问 Azure 门户?

    我想动态创建事件网格主题 每当我的天蓝色函数被触发时 它就会根据它获得的输入创建新主题 我只是想知道如果有什么方法可以创建天蓝色主题 而无需转到天蓝色门户 有一个EventGrid管理库Microsoft Azure 管理 EventGri
  • 用于发现.NET代码依赖关系的工具(不是VS2010)

    给定一个非常大的 NET 代码库 有些部分在源代码中 有些部分在二进制文件中 这都是 NET 代码 我想要一个工具来发现该代码库中的依赖关系 按组件和类型 以图形形式可视化依赖关系会非常好 我想要 实例化图 引用图 调用图 类型依赖关系图
  • 在 haskell 中实现 Alpha 等价

    我想使用此数据定义来定义 Alpha 等价 type Sym Char data Exp Var Sym App Term Exp Lam Sym Exp deriving Eq Read Show 做这个的最好方式是什么 一种方法是将名称
  • 如何删除 git 中的本地存储库? [复制]

    这个问题在这里已经有答案了 我找不到命令 我尝试谷歌搜索 git 删除存储库 删除 git如果您只想删除与 git 相关的信息 分支 版本 请在存储库的根目录中删除该目录 如果你想删除所有内容 git data 代码等 只需删除整个目录即可
  • Gradle 包装器在 Windows 上的 Android 项目中获取错误的 Java 版本

    我在 Windows 上的 Android 项目中使用 gradle 当我执行时 gradlew version在我的项目路径中 错误显示为Could not determine java version from 12 我确实有已安装 J
  • 奇怪的错误,set::begin() 总是返回 const 迭代器

    为什么 set begin 总是返回一个 const 迭代器而不是标准迭代器 35 int test 36 std set
  • 在 MySQL 中将“描述”转换为“创建表”?

    我们可以从描述中获取 创建表 命令 describe 吗 我有一个表 其描述可以从 DESC TableName 获得 我想知道我是否可以了解该表是如何创建的 以便我可以使用相同的命令执行其他操作 我可以得到 sql dump 但我想知道是
  • F# 从 while 循环中中断

    有什么方法可以做到这一点C C 例如 C 风格 for int i 0 i lt 100 i if i 66 break 最简洁的答案是不 您通常会使用一些高阶函数来表达相同的功能 有许多函数可以让您执行此操作 对应于不同的模式 因此 如果
  • IP 地址的索引范围搜索算法

    给定一个包含 100 亿个以 CIDR 表示法表示的 IPv4 范围或两个 IP 之间的 ACL 列表 x x x x y x x x x y y y y 用于测试给定 IP 地址是否满足一个或多个 ACL 范围条件的有效搜索 索引算法是什
  • 在 MVP android 应用程序中演示者之间进行通信

    我正在使用 MVP 模式构建一个小型测试 Android 应用程序 我有两个片段片段 B 我用于滑动抽屉 和片段 A 主片段 两个片段都有自己的演示者 当我单击滑动绘制时 它应该发送消息或调用片段 A 中的方法来更新视图 我想问一下 两个片
  • 如何使用智能卡和 python 发出 TLS 请求?

    我尝试使用 python 库 请求 与受智能卡保护的网站进行通信 这意味着 SSL 中的强身份验证 您必须提供客户端证书 证书和私钥 由于我使用的是智能卡 因此我无法读取普通保护的私钥 只能读取模数 我可以使用 python 库 PyKCS