python本身有很多实现rsa的不错的库,但是由于GIL的问题,不能利用多核,所以我尝试利用ctypes库调用openssl的libcrypto.so来突破多核限制。问题是我不知道libcrypto暴露的方法,不知道调用顺序和入参,网上有个签名的算法,我参照了一下写了这么一段代码:
import ctypes
from ctypes.util import find_library
_libcrypto = find_library('crypto')
sign = 'iYzF0bn6kwUtsqLmTSx8fx...'
cryptor = ctypes.cdll.LoadLibrary(_libcrypto)
RSA_size = cryptor.RSA_size
BIO_free = cryptor.BIO_free
RSA_free = cryptor.RSA_free
RSA_decrypt = cryptor.RSA_private_decrypt
PEM_read_bio_RSAPrivateKey = cryptor.PEM_read_bio_RSAPrivateKey
# RSA_PKCS1_PADDING = cryptor.RSA_NO_PADDING
privkey = '''-----BEGIN RSA PRIVATE KEY-----...-----END RSA PRIVATE KEY-----'''
bio = cryptor.BIO_new_mem_buf(privkey, -1)
key = PEM_read_bio_RSAPrivateKey(bio, 0, 0, 0)
r = BIO_free(bio)
if r != 1:
# break here
print 'BIO_free error'
return
rsa_size = RSA_size(key)
print rsa_size
rsa = ctypes.create_string_buffer(rsa_size)
#sign_size = ctypes.create_string_buffer(4)
ret = RSA_decrypt(len(sign), sign, rsa, key)
其中privkey是私钥,sign是我要解密的数据,然而这段代码并没有返回正确的结果。
想请问大家python调用libcrypto实现RSA解密的正确姿势,当然有其他能够利用多核的方案希望也能不吝赐教!
完全是试出来的结果……
首先base64的文本要转一下
然后RSA_decrypt的第一个入参错了,应该是:
见官网定义:
这里flen是key长度,之前望文生义以为是from_len。
ret>0表示解密成功,结果从rsa.value里取,然后第五个参数是padding的模式,本应该是RSA_PKCS1_PADDING,但是libcrypto.so.6里好像找不到这个常量,我从0到5自己一个个试出来的,估计1是RSA_PKCS1_PADDING,2是SSLV23_PADDING(不一定这么拼),因为之前试过其他库,这两种填充模式才能解出来。