将 RSA 加密代码从 php 转换为 python
Converting RSA encryption code from php to python
我正在尝试连接到我的 python 应用程序中的 api。
所以 api 文档附带了 php 和 asp 示例代码,但没有 python
我很擅长 php 但没有加密经验...我正在尝试使用 [=57] 为 api 重写 python 代码=]样本.
他们将此 class 用于 RSA
https://github.com/AlaFalaki/Pclass/blob/master/libraries/rsa.class.php
(因为它是一个 RSA 库,我猜 python RSA 库会处理这部分):
static function rsa_sign($message, $private_key, $modulus, $keylength) {
$padded = RSA::add_PKCS1_padding($message, false, $keylength / 8);
$number = RSA::binary_to_number($padded);
$signed = RSA::pow_mod($number, $private_key, $modulus);
$result = RSA::number_to_binary($signed, $keylength / 8);
return $result;
}
这就是问题所在 php 符号函数采用 4 个参数使用一些内部函数...但是 python rsa 有 3 个,其中之一就是哈希方法!
rsa.sign(message, priv_key, hash)
Parameters:
message – the message to sign. Can be an 8-bit string or a file-like object. If message has a read() method, it is assumed to be a file-like object.
priv_key – the rsa.PrivateKey to sign with
hash – the hash method used on the message. Use ‘MD5’, ‘SHA-1’, ‘SHA-256’, ‘SHA-384’ or ‘SHA-512’.
我尝试了一些小实验,看看我是否得到相同的输出
所以我在 php
中唱了一个简单的 text
字符串
echo base64_encode(RSA::rsa_sign(sha1("test"),$private_key,$modulus,$key_length));
我得到了
类似
dKt+4CocMNdIrtYCUr8aZykR8CpfmYUEEVONMuAPlM5mR70AoyzMhGjcEGB9fKLVC4rr5xt66w2ZmHqWO+p834rJmo9Fj57udRSY5wFs0VokMF2S2SMFn5WTYYmMBuWciRzZybWnfXcSIyp9Ibi28cdwl5hXJOMpXEJrNQLFy2s=
接下来我从他们给我的 xml 文件中提取 private_key , public_key ,模数 api 包含我的密钥(使用相同的RSA class ) 喜欢
$xmlObj = simplexml_load_string($xmlRsakey);
$this->modulus = RSA::binary_to_number(base64_decode($xmlObj->Modulus));
$this->public_key = RSA::binary_to_number(base64_decode($xmlObj->Exponent));
$this->private_key = RSA::binary_to_number(base64_decode($xmlObj->D));
$this->key_length = strlen(base64_decode($xmlObj->Modulus))*8;
我和他们一起做了一本python字典
def keys():
obj = {
'modulus' : "14417185111734127374105962730273......." ,
'public_key' : "61111" ,
'private_key' : "3739752306322843055980611965983321761993....." ,
'key_length' : 1024 ,
}
return obj
并且我尝试在 python
中签署一个字符串
def sign(request):
api = keys()
message = 'test'
crypto = rsa.sign(message.encode('utf-8'), api['private_key'] , 'SHA-1')
b64 = base64.b64encode(crypto)
return HttpResponse(b64)
但我得到:
'str' object has no attribute 'n'
那是我失败的实验
正如我所说,我没有任何加密或 rsa 方面的经验....我想从使用过这些东西的人那里得到一些建议。
我应该放弃并使用 php 到 encrypt/decrypt 吗?
They use this class for RSA
https://github.com/AlaFalaki/Pclass/blob/master/libraries/rsa.class.php
我的建议:运行远离尖叫。
RSA 是一个安全问题的雷区。有很多事情你可以搞砸。因此,当有人 使用 BC 扩展在 PHP 中实现原语 时,这相当于赤身裸体站在行刑队面前并期望没有漏洞。
- 使用 PKCS1 填充进行加密 allows near-trivial message decryption
- 搞砸你的参数can completely remove all security from your crypto
- 本土 RSA 成熟 side-channel attacks
建议:Use Libsodium改为
libsodium 有 PHP 和 Python 绑定。
如果 RSA 不可避免...
如果您真的想要 RSA 而不是现代密码学,请查看 phpseclib。
<?php
use
$rsa = new RSA();
// HIGHLY RECOMMENDED FOR SECURITY:
$rsa->setEncryptionMode(RSA::ENCRYPTION_OAEP);
$rsa->setMGFHash('sha256');
$rsa->loadKey($yourPEMencodedRSAPublicKey);
$ciphertext = $rsa->encrypt($plaintext);
如果您要使用 RSA 加密,您必须遵循these cryptography rules。如果您的图书馆不允许您遵守这些规则,是时候切换到 libsodium 了。
另请注意,使用 RSA 加密大邮件既缓慢又危险:通常没有任何东西可以阻止邮件重新排序,这可能非常糟糕。
这里的解决方法是:使用对称密钥认证加密,使用RSA加密public密钥。这就是 EasyRSA 所做的,虽然我不知道任何 Python 等价物,所以我不能推荐它作为解决方案。
当然,如果你使用libsodium的crypto_box
API你就不用担心了!
我正在尝试连接到我的 python 应用程序中的 api。 所以 api 文档附带了 php 和 asp 示例代码,但没有 python
我很擅长 php 但没有加密经验...我正在尝试使用 [=57] 为 api 重写 python 代码=]样本.
他们将此 class 用于 RSA
https://github.com/AlaFalaki/Pclass/blob/master/libraries/rsa.class.php
(因为它是一个 RSA 库,我猜 python RSA 库会处理这部分):
static function rsa_sign($message, $private_key, $modulus, $keylength) {
$padded = RSA::add_PKCS1_padding($message, false, $keylength / 8);
$number = RSA::binary_to_number($padded);
$signed = RSA::pow_mod($number, $private_key, $modulus);
$result = RSA::number_to_binary($signed, $keylength / 8);
return $result;
}
这就是问题所在 php 符号函数采用 4 个参数使用一些内部函数...但是 python rsa 有 3 个,其中之一就是哈希方法!
rsa.sign(message, priv_key, hash)
Parameters:
message – the message to sign. Can be an 8-bit string or a file-like object. If message has a read() method, it is assumed to be a file-like object.
priv_key – the rsa.PrivateKey to sign with
hash – the hash method used on the message. Use ‘MD5’, ‘SHA-1’, ‘SHA-256’, ‘SHA-384’ or ‘SHA-512’.
我尝试了一些小实验,看看我是否得到相同的输出
所以我在 php
中唱了一个简单的text
字符串
echo base64_encode(RSA::rsa_sign(sha1("test"),$private_key,$modulus,$key_length));
我得到了
类似
dKt+4CocMNdIrtYCUr8aZykR8CpfmYUEEVONMuAPlM5mR70AoyzMhGjcEGB9fKLVC4rr5xt66w2ZmHqWO+p834rJmo9Fj57udRSY5wFs0VokMF2S2SMFn5WTYYmMBuWciRzZybWnfXcSIyp9Ibi28cdwl5hXJOMpXEJrNQLFy2s=
接下来我从他们给我的 xml 文件中提取 private_key , public_key ,模数 api 包含我的密钥(使用相同的RSA class ) 喜欢
$xmlObj = simplexml_load_string($xmlRsakey);
$this->modulus = RSA::binary_to_number(base64_decode($xmlObj->Modulus));
$this->public_key = RSA::binary_to_number(base64_decode($xmlObj->Exponent));
$this->private_key = RSA::binary_to_number(base64_decode($xmlObj->D));
$this->key_length = strlen(base64_decode($xmlObj->Modulus))*8;
我和他们一起做了一本python字典
def keys():
obj = {
'modulus' : "14417185111734127374105962730273......." ,
'public_key' : "61111" ,
'private_key' : "3739752306322843055980611965983321761993....." ,
'key_length' : 1024 ,
}
return obj
并且我尝试在 python
中签署一个字符串def sign(request):
api = keys()
message = 'test'
crypto = rsa.sign(message.encode('utf-8'), api['private_key'] , 'SHA-1')
b64 = base64.b64encode(crypto)
return HttpResponse(b64)
但我得到:
'str' object has no attribute 'n'
那是我失败的实验
正如我所说,我没有任何加密或 rsa 方面的经验....我想从使用过这些东西的人那里得到一些建议。
我应该放弃并使用 php 到 encrypt/decrypt 吗?
They use this class for RSA
https://github.com/AlaFalaki/Pclass/blob/master/libraries/rsa.class.php
我的建议:运行远离尖叫。
RSA 是一个安全问题的雷区。有很多事情你可以搞砸。因此,当有人 使用 BC 扩展在 PHP 中实现原语 时,这相当于赤身裸体站在行刑队面前并期望没有漏洞。
- 使用 PKCS1 填充进行加密 allows near-trivial message decryption
- 搞砸你的参数can completely remove all security from your crypto
- 本土 RSA 成熟 side-channel attacks
建议:Use Libsodium改为
libsodium 有 PHP 和 Python 绑定。
如果 RSA 不可避免...
如果您真的想要 RSA 而不是现代密码学,请查看 phpseclib。
<?php
use
$rsa = new RSA();
// HIGHLY RECOMMENDED FOR SECURITY:
$rsa->setEncryptionMode(RSA::ENCRYPTION_OAEP);
$rsa->setMGFHash('sha256');
$rsa->loadKey($yourPEMencodedRSAPublicKey);
$ciphertext = $rsa->encrypt($plaintext);
如果您要使用 RSA 加密,您必须遵循these cryptography rules。如果您的图书馆不允许您遵守这些规则,是时候切换到 libsodium 了。
另请注意,使用 RSA 加密大邮件既缓慢又危险:通常没有任何东西可以阻止邮件重新排序,这可能非常糟糕。
这里的解决方法是:使用对称密钥认证加密,使用RSA加密public密钥。这就是 EasyRSA 所做的,虽然我不知道任何 Python 等价物,所以我不能推荐它作为解决方案。
当然,如果你使用libsodium的crypto_box
API你就不用担心了!