在最新的 Python 3 版本中实现“openssl_private_encrypt”

2023-12-08

我正在尝试用 Python 维护 FastSpring 电子商务平台 Secure Payload api 实现。

他们的文档提供了使用 Java 和 PHP 中的私钥加密(或技术上签名?)有效负载的示例:https://developer.fastspring.com/docs/pass-a-secure-request#locally-encrypt-the-session-object

我之前一直使用基于此存储库的基于 Python“密码学”库的实现:https://github.com/klokantech/flask-fastspring/blob/0462833f67727cba9755a26c88941f11f0159a48/flask_fastspring.py#L247

然而,这依赖于未记录的 openssl“_lib.RSA_private_encrypt()”函数,该函数在高于 2.9.2 的加密版本中不再公开,该版本已经有几年的历史了。对于最新的 python 版本,它不再包含二进制包,PIP 必须从源代码编译它。

PyCryptodome 似乎包含类似的 RSA 私钥签名和 PKCS #1 v1.5 填充,但它要求有效负载是哈希对象,因此无论我使用什么哈希函数,生成的输出自然都不符合 FastSpring 的期望:https://pycryptodome.readthedocs.io/en/latest/src/signature/pkcs1_v1_5.html?highlight=pkcs1_15#pkcs-1-v1-5-rsa

我一直在尝试寻找任何替代方法来实现这种“私钥加密”,但没有成功。所以我的问题是:有没有办法用最新的 python 库来做到这一点,或者我是否坚持使用过时的加密库,直到它不再受支持?


这两个链接代码使用以下方式实现低级签名RSASSA-PKCS1-v1_5,但消息使用的是修改后的编码,而不是EMSA-PKCS1-v1_5,因此处理与标准不同。

两个主要的 Python 加密库PyCryptodome and 密码学只支持高级签名,它封装了entire过程遵循标准,因此不允许对消息的编码进行任何修改。

解决该问题的最有效方法是使用还支持低级签名的 Python 库,以便可以使用链接的 Java 或 Python 代码中的消息编码。但是,我不知道有这样的图书馆。

如果您也不知道这样的库,还有以下替代方案:由于 RSASSA-PKCS1-v1_5 非常简单,并且 Python 本身支持大整数及其操作,因此可以将自定义实现与辅助函数相结合,例如PyCryptodome很容易成为可能。至少你不必再依赖遗留库了:

from Crypto.Util import number

def customizedSign(key, msg):
    
    modBits = number.size(key.n)
    k = number.ceil_div(modBits, 8) 
  
    ps = b'\xFF' * (k - len(msg) - 3)
    em = b'\x00\x01' + ps + b'\x00' + msg 
  
    em_int = number.bytes_to_long(em)
    m_int = key._decrypt(em_int) 
    signature = number.long_to_bytes(m_int, k)
    
    return signature

解释:
实施遵循PyCryptodome的实施sign()方法。这only功能差异在于,使用链接代码的编码而不是 EMSA-PKCS1-v1_5。 EMSA-PKCS1-v1_5 定义为:

EM = 0x00 || 0x01 || PS || 0x00 || T

where T是 DER 编码的 DigestInfo 值和散列消息的串联,请参阅here.
链接代码的编码仅使用消息MSG代替T:

EM = 0x00 || 0x01 || PS || 0x00 || MSG 

在这两种情况下,PS是一个填充,其值是 0xFF,最高可达密钥大小(即模数的大小)。

使用及测试:

由于签名是确定性的,因此相同的密钥和相同的消息始终提供相同的签名。这样就很容易证明上面的函数等价于链接的 Java 或 Python 代码:

from Crypto.PublicKey import RSA
import base64

# For simplicity, a 512 bits key is used. Note that a 512 bits key may only be used for testing, in practice the key size has to be >= 2048 bits for security reasons.
pkcs8 = """-----BEGIN PRIVATE KEY-----
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA2gdsVIRmg5IH0rG3
u3w+gHCZq5o4OMQIeomC1NTeHgxbkrfznv7TgWVzrHpr3HHK8IpLlG04/aBo6U5W
2umHQQIDAQABAkEAu7wulGvZFat1Xv+19BMcgl3yhCdsB70Mi+7CH98XTwjACk4T
+IYv4N53j16gce7U5fJxmGkdq83+xAyeyw8U0QIhAPIMhbtXlRS7XpkB66l5DvN1
XrKRWeB3RtvcUSf30RyFAiEA5ph7eWXbXWpIhdWMoe50yffF7pW+C5z07tzAIH6D
Ko0CIQCyveSTr917bdIxk2V/xNHxnx7LJuMEC5DcExorNanKMQIgUxHRQU1hNgjI
sXXZoKgfaHaa1jUZbmOPlNDvYYVRyS0CIB9ZZee2zubyRla4qN8PQxCJb7DiICmH
7nWP7CIvcQwB
-----END PRIVATE KEY-----""" 

key = RSA.import_key(pkcs8)
msg = 'The quick brown fox jumps over the lazy dog'.encode('utf8')
signature = customizedSign(key, msg)

print(base64.b64encode(signature).decode('utf8')) # OwpVG/nPmkIbVxONRwXHvOqLdYNnP67YtiWA+GcKBZ3rIzAJ+8izvmlqUQnzVp03Wrrzq2ogUmCMaLSPlInDNw==

链接的 Java 代码为相同的密钥和消息提供相同的签名。

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

在最新的 Python 3 版本中实现“openssl_private_encrypt” 的相关文章

  • pyvenv-3.4 返回非零退出状态 1

    我在 Kubuntu 14 04 我想用 python3 4 创建一个 virtualenv 我之前在其他文件夹中使用过 python2 7 但是当我尝试时 pyvenv 3 4 venv 我有 Error Command home fmr
  • 在 Pandas 数据框中显示对图

    我试图通过从 pandas 数据框中的 scatter matrix 创建来显示一对图 这就是创建配对图的方式 Create dataframe from data in X train Label the columns using th
  • 动态添加字段到数据类对象

    我正在编写一个库来访问 REST API 它返回带有用户对象的 json 我将其转换为 dict 然后将其转换为数据类对象 问题是并非所有字段都是固定的 我想动态添加其他字段 未在我的数据类中指定 我可以简单地为我的对象分配值 但它们不会出
  • 使用 xlwings 排序(pywin32)

    我需要使用 python 按给定行对 Excel 电子表格进行排序 为了进行测试 我使用以下数据 在名为 xlwings sorting xlsx 的文件中 Numbers Letters Letters 2 7 A L 6 B K 5 C
  • Python列表内存存储[重复]

    这个问题在这里已经有答案了 据我了解 Python 列表本质上是 C 数组 它们分配特定的顺序内存块 但是 这些内存块实际上存储列表中的数据还是它们只是指向内存中存储实际数据的另一个位置 它可能取决于列表中存储的对象的大小吗 因为您可以轻松
  • 将 pandas DataFrame 中的数字转换为特定字符串格式

    我需要运行一个可以通过循环完成的任务 但我想有一种更有效 更漂亮的方法来做到这一点 我有一个DataFrame它有一个整数列 我想将其转换为 4 位字符串表示形式 也就是说 3 应转换为 0003 234 应转换为 0234 我正在寻找一种
  • 在 Linux 中重新启动时,新创建的文件变为 0 kb(数据被覆盖为空)

    我遇到了一个奇怪的问题 这让我发疯 当前的任务是在 root 用户第一次登录时启动一组文件 并在同一用户第二次登录时启动另一组文件 我决定使用 profile 和 bashrc 文件 并在第一次登录期间发生的任务结束时重新加载 bashrc
  • python sqlite3从excel创建数据库

    我正在尝试从 Excel 电子表格创建数据库 我有下面的代码 问题是当我运行代码时 我的数据库为每列创建一个表 我想为工作簿中列出的每个电子表格创建一个表格 工作表名称为工作表 1 和工作表 2 import sqlite3 import
  • 除下一行的值并在数据框中创建列

    我有一个像这样的csv id value 1 100 1 150 1 200 1 250 2 300 2 350 2 400 2 450 我想根据每个唯一 ID 的值生成一列 例如 id 1 的前 2 行值为 100 150 我正在尝试创建
  • 编程式 Google 登录/注销用户 1,然后登录用户 2 (Python)

    我正在开展一个 DIY 项目 为我的家庭中的多个成员检索 Google 位置历史记录 根据 StackOverflow 成员的指示 t m 亚当 https stackoverflow com users 7811673 t m adam
  • 导入错误 - 发生了什么?

    Python 导入 再次 我有这个文件结构 test start py from scripts import main scripts init py empty main py from import install install p
  • Python 3 中的相对导入

    我想从同一目录中的另一个文件导入函数 通常 以下其中一项有效 from mymodule import myfunction from mymodule import myfunction 但另一个给了我以下错误之一 ImportError
  • Selenium Python Firefox webdriver:无法修改配置文件

    我想在 Webdriver Firefox 实例上使用 新选项卡而不是窗口 选项 1 我创建了一个启用此选项的配置文件 但是当我使用该配置文件时 很多选项都可以 但不是这个 2 加载配置文件后 我尝试更改代码中的选项 但它不起作用 我的代码
  • FastAPI/Pydantic 接受任意 post 请求正文吗?

    我想创建一个 FastAPI 端点 它只接受任意的 post 请求正文并返回它 如果我发送 foo bar 我想得到 foo bar 后退 但我也希望能够发送 foo1 bar1 foo2 bar2 并把它拿回来 我试过 from fast
  • Windows7上python3.5无法安装BeautifulSoup4

    我已经从下载了 beautifulsoup4 4 5 3 tar gzhttps www crummy com software BeautifulSoup bs4 download 4 5 https www crummy com sof
  • 无法使用 beautifulsoup 模块 python 从 HTML 检索温度值

    我正在使用 BeautifulSoup4 来解析此 HTML 查看源代码 https weather com en IN weather today l 17 39 78 49 https weather com en IN weather
  • Python3如何安装.ttf字体文件?

    我想使用 python3 更精确的 Python 3 6 代码在 Windows 10 上安装 ttf 字体文件 我用谷歌搜索 但我发现的唯一的就是这个使用python在windows上安装TTF字体 https stackoverflow
  • 计算 RSA 128 位密钥长度需要多长时间? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我在网上做了一些研究 似乎表明 RSA 加密的推荐密钥长度是 1024 位 但是我有一个问题 对于今天使用的普通计算机来说 计算 128 位 RSA
  • 如何将交互式 matplotlib 图形插入 tkinter 画布

    我正在尝试将交互式 matplotlib 图形 具有滑块 重置按钮和单选按钮的图形 放入 tkinter Canvas 中 我已成功添加非交互式图表 但当它变为交互式时找不到问题 我尝试将所有内容更改为使用 matplotlib Figur
  • 给定两个 SSH2 密钥,我如何检查它们是否属于 Java 中的同一密钥对?

    我正在尝试找到一种方法来验证两个 SSH2 密钥 一个私有密钥和一个公共密钥 是否属于同一密钥对 我用过JSch http www jcraft com jsch 用于加载和解析私钥 更新 可以显示如何从私钥 SSH2 RSA 重新生成公钥

随机推荐

  • 如何计算具有指数的字符串

    Javax ScriptEngine 和 JEval 的工作原理类似 您输入一个字符串并将其发送给它进行评估 它会返回您的结果 在 ScriptEngine 中 在 JEval 中几乎相同 System out println engine
  • VSCode:快速切换flutter版本

    所以 我使用的是 flutter 2 2 3 版本 现在无法升级 但是 我的另一个项目需要更高的SDK 我知道 有FVM 但我发现了这个 如何在同一设备上针对不同项目使用两个版本的flutter 并引用文章 https dartcode o
  • c#: SetScrollPos (user32.dll)

    我想要 2 个 丰富的 文本框 bc 2k8 具有相同的滚动 所以当我滚动 tb1 时 tb2 滚动到相同的位置 我使用这个功能 DllImport user32 dll static extern int SetScrollPos Int
  • Go 中空接口的最佳实践?

    我正在学习空接口 我发现虽然在 Stackoverflow 上有很多关于空接口的含义及其工作方式的解释 但关于何时 为何使用它们 何时避免 考虑因素是什么以及如何使用它们的最佳实践信息却很少 选择使用它们的优点和缺点 在 Go 聊天室中 我
  • knit/rmarkdown/Latex:如何交叉引用图形和表格?

    我正在尝试交叉引用使用knitr rmarkdown 生成的PDF 中的图形和表格 关于 SO 和 tex stackexchange 有一些问题 here and here 例如 建议内联执行此操作的方法是添加 ref fig my fi
  • 将 _blank 添加到所有外部链接[重复]

    这个问题在这里已经有答案了 可能的重复 获取 A 元素的 href 属性 解析 href 标签中包含特定单词的所有链接 我使用以下函数将 blank 添加到我网站上的所有链接 function targetBlank text return
  • PHP 中的 curl_setopt() 中 RETURNTRANSFER 常量的用途

    我想了解 PHP 中curl 的工作细节 有什么用curl setopt ch curl returntransfer true 我搜索了很多网站但没有得到答案 那么请告诉我这个特殊的功能 为什么我们使用CURL RETURNTRANSFE
  • 重复的局部变量和变量无法解析

    我的 java 代码中出现了三个不同的错误 有什么帮助吗 错误一 重复的局部变量乘积 int product input nextInt 错误 2 productTotal 无法解析为变量 System out printf 10 2f n
  • setTimeout 存在字段更新的循环问题

    我正在尝试循环遍历计时器上的列表 当前为 1 秒 但我希望它更快 问题是当前值没有在视觉上更新 我不明白为什么 当我循环遍历时Firebug it works按预期但没有萤火虫它没有显示文本更改 它是否以某种方式跳过文本更新 我把定时器设置
  • 如何使用 xml starlet 插入实体

    我试图用包含 符号的文本替换属性值
  • iOS 中捆绑资源中的 Sqlite3

    您好 我计划从我的项目资源文件夹添加静态 SQLite3 但我不知道我是否正确执行 到目前为止 这是我的进展 创建 SQLite3 数据库SQLite 数据库浏览器 Copied Sqlite3 Database to my project
  • 经典 ASP、MySQL 或 ODBC UTF8 编码

    我有一个由 GoDaddy 托管的网站 包括后端的 MySQL 数据库 该网站是斯洛文尼亚网站 因此使用了特殊字符 该网站是用经典 ASP 构建的 我在 Notepad 中创建了所有页面 其中使用了 utf 8 编码 在每个页面的顶部 我还
  • 使用curl POST multipart/form-data 的正确方法是什么?

    我使用此语法来发布文件以及一些参数 curl v include form key1 value1 form upload localfilename URL 该文件大小约为 500K 首先 我看到发送端的内容长度为 254 之后服务器响应
  • 如何使用python下载谷歌云平台上文件夹内的文件?

    from google cloud import storage client storage Client bucket client get bucket bucket name blob bucket get blob path to
  • 可变递归预处理器宏 - 可能吗?

    我遇到了一些理论问题 在我维护的一段代码中有一组宏 例如 define MAX OF 2 a b a gt b a b define MAX OF 3 a b c MAX OF 2 MAX OF 2 a b c define MAX OF
  • 将 Yii2 应用程序部署到共享主机步骤

    我觉得奇怪的是 关于将 Yii2 应用程序部署到共享主机服务器的注意事项的详细信息如此之少 如果有的话 有人对此有一些步骤 技巧 注意事项吗 您是否遵循一个流程可以将问题 错误降至最低 数据库如何迁移 带有数据 我假设我可以导出 导入数据库
  • C# 比较两个泛型值[重复]

    这个问题在这里已经有答案了 可能的重复 运算符 不能应用于 C 中的泛型类型吗 我编写了这样的代码 public bool IsDataChanged T value1 GetValue2 T value2 GetValue1 return
  • 模块 appregistry 不是已注册的可调用模块(调用 runApplication)

    我根本找不到让反应导航工作的方法 我从互联网上复制了工作示例 但它们似乎也不起作用 有人可以告诉我我做错了什么吗 我在用着 节点 8 9 4 反应 16 3 0 alpha 1 反应本机 0 54 0 反应导航 1 4 0 index js
  • 谷歌地图折线的中间(质心?)

    我有一个折线列表 就像谷歌地图一样does当我单击折线时 我希望在我单击的位置显示一个信息窗口 并且它与此功能配合得很好 function mapsInfoWindow polyline content google maps event
  • 在最新的 Python 3 版本中实现“openssl_private_encrypt”

    我正在尝试用 Python 维护 FastSpring 电子商务平台 Secure Payload api 实现 他们的文档提供了使用 Java 和 PHP 中的私钥加密 或技术上签名 有效负载的示例 https developer fas