最新消息:

python中使用public key做RSA加密

未分类 admin 10799浏览 0评论

这一个星期在用python实现写一个命令行的飞信发信息小工具,为了放在服务器监控程序中用于短信报警。飞信在做用户认证时会先把一个RSA公钥传给客户端,客户端用这个RSA公钥做加密,然后把加密后的16进制串送到远端去验证。

我是个业余码农,所谓的cryptography,即密码学,那是几乎没接触过。通过wiki和google,对RSA简单了解了一下,然后找了一下如何用python来做RSA加密的方法,多数都提到了pycrypto和M2Crypto这两个模块(都是对openssl的封装)。

飞信传给客户端的公钥key由两部分组成,就是RSA公钥的exponent(俗称e)和modulus(俗称n),通过exponent和modulus来生成真正的public key。我就卡在了如何用现成的python模块来使用e和n做公钥加密。一般情况下,都是通过导入PEM结构的公钥来做RSA加密,而我只有e和n,怎么把它们转化成PEM结构呢?

后来发现M2Crypto有一个new_pub_key((e, n)) 方法可以导入e和n来生成公钥,可是它有格式的限制:

e (string) – The RSA public exponent; it is a string in OpenSSL’s MPINT format – 4-byte big-endian bit-count followed by the appropriate number of bits.
n (string) – The RSA composite of primes; it is a string in OpenSSL’s MPINT format – 4-byte big-endian bit-count followed by the appropriate number of bits.

也不知道这OpenSSL’s MPINT format 是什么标准的格式,我没捣鼓出来。
然后又试用pycrypto模块,它也有一个类似的方法:RSA.construct((n, e))。惊喜的发现它只要传入long型的参数,就能正常工作。可是,飞信登录验证时的RSA加密用到的是RSA_PKCS1_PADDING 填充模式,pycrypto没有提供模式选择(有patch可以实现,未证实)。
懒惰的我最终决定由pycrypto使用e和n生成公钥,导出为PEM格式,再把这个PEM的公钥提供给M2Crypto,是不是很蛋疼?

几行示例:

import Crypto.PublicKey.RSA
import M2Crypto.BIO
import M2Crypto.RSA
.........................
rsakey = Crypto.PublicKey.RSA.construct((n, e))
public_key = rsakey.publickey().exportKey()
bio = M2Crypto.BIO.MemoryBuffer(tmpkey)
rsa = M2Crypto.RSA.load_pub_key_bio(bio)
rsa.public_encrypt('要加密的东东',M2Crypto.RSA.pkcs1_padding))
我还试过用ctypes来调用openssl的函数,结果表示可行。

我知道这样的实现很ugly,在python中有没有更直接的方法使用e和n做RSA公钥加密的呢?

转载请注明:爱开源 » python中使用public key做RSA加密

您必须 登录 才能发表评论!