我正在尝试在Python维护Fastspring电子商务平台安全有效负载API实现。
他们的文档中有示例用于加密(或技术上签名?)Java和php中使用私钥的有效载荷: https://developer.fastspring.com/docs/pass-a-secure-request-request#locally-cencrypt-eccrypt-censession-sessise-object
,我有以前是基于此存储库的基于Python“密码学”库的实现:
,
但是,该依靠无证件的OPENSSL openssl“ _lib.rib.rsa_rib.rsa_private_encrivate_encrivate_encrivate_encrypt()较高,该函数的函数更高。借助最新的Python版本,它不再包含二进制包,并且PIP必须从源头进行编译。
pycryptodome似乎包括与PKCS#1 V1.5填充的类似RSA私钥签名,但是它要求有效载荷是一个哈希对象,因此自然而然地,生成的输出与FastSpring所期望的不符合我使用的hash功能,而我使用的是什么:<
pkcs1_15#pkcs-1-v1-5-rsa 没有成功的“私钥加密”。因此,我的问题是:有什么方法可以使用最新的Python库进行此操作,还是我坚持使用过时的密码库,直到根本不再支持它?
I'm trying to maintain FastSpring e-commerce platform Secure Payload api implementation in Python.
Their documentation has examples for encrypting (or technically signing?) the payload with private key in Java and PHP: https://developer.fastspring.com/docs/pass-a-secure-request#locally-encrypt-the-session-object
And I have been previously using a Python "cryptography" library based implementation based on this repository:
https://github.com/klokantech/flask-fastspring/blob/0462833f67727cba9755a26c88941f11f0159a48/flask_fastspring.py#L247
However, that relies on undocumented openssl "_lib.RSA_private_encrypt()" function that is no longer exposed in cryptography versions higher than 2.9.2, which is already several years old. And with latest python versions it no longer includes binary packages and PIP must compile it from source.
PyCryptodome seems to include similar RSA private key signing with PKCS #1 v1.5 padding, but it requires payload to be a Hash object, so naturally the produced output doesn't match what FastSpring expects regardless of what Hash function I use: https://pycryptodome.readthedocs.io/en/latest/src/signature/pkcs1_v1_5.html?highlight=pkcs1_15#pkcs-1-v1-5-rsa
I have been trying to figure out any alternative ways to implement this kind of "private key encryption" without success. So my question is: Is there ANY way to do this with up-to-date python libraries or am I stuck to use an outdated cryptography library until it no longer is supported at all?
发布评论
评论(1)
这两个链接的代码使用 rsassa-pkcs1-v1_5 ,但修改后的编码用于消息而不是,因此处理与标准不同。
两个主要的python加密库 pycryptodome 和加密 仅支持封装整个整个过程的高级签名,遵循标准,因此不允许对消息编码进行任何修改。
解决问题的最有效方法是使用也支持低级签名的Python库,以便可以使用链接的Java或Python代码的消息编码。但是,我不知道这样的图书馆。
如果您也不知道这样的库,则有以下选择:因为RSASSA-PKCS1-V1_5非常简单,Python支持大整数及其操作,因此与EG 的辅助功能结合使用了自定义实现。 pycryptodome 很容易。至少您不必再依靠旧库:
说明:
该实现遵循
pycryptodome
sign()
方法。 仅功能差异是,使用链接代码的编码代替EMSA-PKCS1-V1_5。EMSA-PKCS1-V1_5定义为:
其中
t
是DER编码的DigestInfo值的串联和Hashed消息的串联,请参见在这里。链接代码的编码只需使用消息
msg
而不是t
:在两种情况下,
ps ps
是一个带有0xff值的填充物钥匙大小(即模量的大小)。用法和测试:
由于签名是确定性的,因此相同的密钥和相同的消息始终提供相同的签名。这样,很容易证明上述功能等效于链接的Java或Python代码:
链接的Java代码为相同的密钥和消息提供了相同的签名。
The two linked codes implement low level signing using RSASSA-PKCS1-v1_5, but a modified encoding is used for the message rather than EMSA-PKCS1-v1_5, and therefore the processing differs from the standard.
The two major Python crypto libraries PyCryptodome and Cryptography only support high level signing, which encapsulates the entire process, follows the standard and thus does not allow any modification of the encoding of the message.
The most efficient way to solve the problem would be to use a Python library that also supports a low level signing, so that the encoding of the message from the linked Java or Python code can be used. However, I am not aware of such a library.
If you don't know such a library either, there is the following alternative: Since RSASSA-PKCS1-v1_5 is pretty simple and Python supports large integers and their operations natively, a custom implementation in combination with the helper functions of e.g. PyCryptodome is easily possible. At least you wouldn't have to rely on the legacy library anymore:
Explanation:
The implementation follows the
PyCryptodome
implementation of thesign()
method. The only functional difference is that instead of EMSA-PKCS1-v1_5 the encoding of the linked codes is used.EMSA-PKCS1-v1_5 is defined as:
where
T
is the concatenation of the DER encoded DigestInfo value and the hashed message, see here.The encoding of the linked codes simply uses the message
MSG
instead ofT
:In both cases,
PS
is a padding with 0xFF values up to the key size (i.e. size of the modulus).Usage and test:
Since the signature is deterministic, the same key and the same message always provide the same signature. This way it is easy to show that the above function is equivalent to the linked Java or Python code:
The linked Java code provides the same signature for the same key and message.