在Python(PyCrypto)和PHP(OpenSSL)中进行RSA加密兼容 [英] Making RSA encryption compatible in Python (PyCrypto) and PHP (OpenSSL)

查看:294
本文介绍了在Python(PyCrypto)和PHP(OpenSSL)中进行RSA加密兼容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在迁移整个PHP API,而在使用PyCrypto之前,我不知道如何翻译以下加密调用,因为我需要完全相同的结果。 PHP调用是:

I am migrating an entire PHP API, and while I used PyCrypto before, I am not sure how to translate the following encryption call, since I need the exact same result. The PHP call is:

define('KEY', "-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC81t5iu5C0JxYq5/XNPiD5ol3Z
w8rw3LtFIUm7y3m8o8wv5qVnzGh6XwQ8LWypdkbBDKWZZrAUd3lybZOP7/82Nb1/
noYj8ixVRdbnYtbsSAbu9PxjB7a/7LCGKsugLkou74PJDadQweM88kzQOx/kzAyV
bS9gCCVUguHcq2vRRQIDAQAB
-----END PUBLIC KEY-----");
$cypher = "";
$result = openssl_public_encrypt($plain, $cypher, KEY, OPENSSL_PKCS1_PADDING);
echo bin2hex($cypher);

假设一切顺利,则从 $ cypher ,传递到十六进制。对于一个采样输入 azzzzzzzzzzzzdfdf我得到的是这样的: 2281aeebc1166cdfb2f17a0a0775d927ca5a9ad999bae0e4954f58bd8082fdf7efe1fd284876530341f714456d7eb8cd44c57b20ab27029b84d5dc77a674bede3fe9065282931404286082e9df8607bdcff0818b90324dfee7d76b566d0f99bebc5cc913372c276ba373712128f1bcc226b59367cff93f7cdd6dbde25b366863

Assuming everything goes right, this prints the content from $cypher, passed to hexadecimal. For a sample input "azzzzzzzzzzzzdfdf" I get something like: "2281aeebc1166cdfb2f17a0a0775d927ca5a9ad999bae0e4954f58bd8082fdf7efe1fd284876530341f714456d7eb8cd44c57b20ab27029b84d5dc77a674bede3fe9065282931404286082e9df8607bdcff0818b90324dfee7d76b566d0f99bebc5cc913372c276ba373712128f1bcc226b59367cff93f7cdd6dbde25b366863".

我必须假设这个值是正确的,因为代码是从我正在迁移的现有API中获取的。但是,尝试使用 PyCrypto (是的,我正在将API迁移到Python中),我使用以下代码:

I must assume this value as right, since the code was taken from an existing API I am migrating. However, trying the same with PyCrypto (yes, I am migrating the API to be available in Python), I use the following code:

def bin2hex(s):
    return "".join([hex(ord(c))[2:].zfill(2) for c in s])

KEY = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC81t5iu5C0JxYq5/XNPiD5ol3Z
w8rw3LtFIUm7y3m8o8wv5qVnzGh6XwQ8LWypdkbBDKWZZrAUd3lybZOP7/82Nb1/
noYj8ixVRdbnYtbsSAbu9PxjB7a/7LCGKsugLkou74PJDadQweM88kzQOx/kzAyV
bS9gCCVUguHcq2vRRQIDAQAB
-----END PUBLIC KEY-----"""

from Crypto.Cipher import PKCS1_v1_5
from Crypto.PublicKey import RSA
encrypter = PKCS1_v1_5.new(RSA.importKey(KEY))
print bin2hex(encrypter.encrypt("azzzzzzzzzzzzdfdf"));

虽然我希望返回和打印相同的值,但值最终为 3dd94ffabd01bb0e94010c0fedbcd4eb648f12e5d9e6d934b77ae86f76681d8a1b790cad9fddf6e6720415b4d645e525c33c402fa9778739b8e461790387e9508f7158a5fdc5723f5fc26d166b11a00759f0e0ee3ba6719a2e7c6b918f66e1311d1fff878ee2ca8762e1d6120f1e9585a76cdc7719ca20129ae76182b4277170

While I expect the same value be returned and printed, the value finally is "3dd94ffabd01bb0e94010c0fedbcd4eb648f12e5d9e6d934b77ae86f76681d8a1b790cad9fddf6e6720415b4d645e525c33c402fa9778739b8e461790387e9508f7158a5fdc5723f5fc26d166b11a00759f0e0ee3ba6719a2e7c6b918f66e1311d1fff878ee2ca8762e1d6120f1e9585a76cdc7719ca20129ae76182b4277170".

使用 PKCS1_OAEP 输出290f60f37088c2cb46ae9221b01ff46a463f270ef7cf70bbea49de0b5ae43aec34a0eb46e694cf22f689eb77e808c590fdc30eda09f9d3f3cb8c15e0505bf5a984c2a121bc9fa83c6b5ccf50235f072467b4ae9cdf0f0ee2e486626ffa62ad1aa715fbe29e8afe4ceab3ca5a5df4c1dc75d7f258285d7ff1f4f2b4dcb7a8413a

很容易告诉我必须修复我的python代码。如何修复我的python代码,所以它返回与给定的PHP调用完全相同的结果?

It is easy to tell that I must fix my python code. How can I fix my python code so it returns the exact same result as the given PHP call?

推荐答案

你的代码很好。 PKCS#1 v1.5填充pyCrypto是随机的()。因此即使使用相同的密钥和明文,加密也将永远是不同的。这是一个理想的属性。

Your code is fine. PKCS#1 v1.5 padding in pyCrypto is randomized (source). So the encryption will always be different even if you use the same key and plaintext. This is a desirable property.

如果要检查pyCrypto和PHP的OpenSSL扩展之间的兼容性,那么您需要一个加密,另一个解密,并检查你得到了你的期望。

If you want to check compatibility between pyCrypto and PHP's OpenSSL extension, then you would need to encrypt in one, decrypt in the other and check that you got what you expected.

PKCS#1 v1.5填充现在不应该被使用,因为有高效的攻击反对。 OAEP是一个更好的选择。

PKCS#1 v1.5 padding should not be used nowadays, because there are efficient attacks against it. OAEP is a much better alternative.

这篇关于在Python(PyCrypto)和PHP(OpenSSL)中进行RSA加密兼容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆