将RSA加密代码从php转换为python

时间:2016-06-16 20:22:59

标签: php python django encryption rsa

我正在尝试连接到我的python应用程序中的api。 因此api文档带有php和asp示例代码,但没有python

我对PHP非常好,但没有加密经验...我正在尝试使用php示例为api重写python代码。

他们将此类用于RSA

 https://github.com/AlaFalaki/Pclass/blob/master/libraries/rsa.class.php

(因为它是一个RSA lib我猜猜python RSA lib会处理这个部分):

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 sign函数需要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类),如

$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来加密/解密吗?

1 个答案:

答案 0 :(得分:1)

  

他们将此类用于RSA

function fun(){ return this; }
fun.prototype.firstname = 'yogesh';
fun.prototype.lastname = 'jagdale';

var f = new fun();

for(var proto in f.constructor.prototype){
   console.log(proto)
}

我的建议:尖叫着逃跑。

RSA是一个安全问题的雷区。你可以搞砸很多事情。因此,当某人使用BC扩展在PHP中实现原语时,这就相当于在一个行刑队前赤身裸体并且期望没有漏洞。

建议:Use Libsodium而不是

libsodium有PHP和Python绑定。

如果RSA不可避免......

如果你真的想要RSA而不是现代加密技术,请查看phpseclib

https://github.com/AlaFalaki/Pclass/blob/master/libraries/rsa.class.php

如果您要使用RSA加密,必须关注these cryptography rules。如果您的图书馆不允许您遵守这些规则,则可以切换到libsodium。

另请注意,使用RSA加密大型邮件既缓慢又危险:通常没有什么可以阻止邮件重新排序,这可能非常糟糕。

此处的解决方案是:使用对称密钥身份验证加密并使用RSA加密公钥。这就是EasyRSA所做的,虽然我不知道任何Python等价物,所以我不能推荐它作为解决方案。

当然,如果您使用libsodium的<?php use $rsa = new RSA(); // HIGHLY RECOMMENDED FOR SECURITY: $rsa->setEncryptionMode(RSA::ENCRYPTION_OAEP); $rsa->setMGFHash('sha256'); $rsa->loadKey($yourPEMencodedRSAPublicKey); $ciphertext = $rsa->encrypt($plaintext); API,则无需担心!