至少对于一个C程序员来说是这样..
有一段RSA签名的程序,原本是用 C 调 libcrypto 包装成 jni 由 java 使用的,现在打算在 python 里面实现一个类似的功能,这段 C 代码大概是这样:
int rsa_sign(char *private_keyfile, char *message, int message_len, char *buf, int buf_size)
{
RSA *key;
int malloc_size, rsa_size; unsigned char *rsa;
BIO *bio;
bio = BIO_new_file(private_keyfile, "r");
if (NULL == bio) {
return 0;
}
key = (RSA *)PEM_read_bio_RSAPrivateKey(bio, NULL, NULL, NULL);
BIO_free(bio);
if (NULL == key) {
return 0; }
malloc_size = RSA_size(key);
rsa = (unsigned char *)malloc(malloc_size);
if (NULL == rsa) {
RSA_free(key);
return 0; }
if (0 == RSA_sign(NID_md5, message, message_len, rsa, &rsa_size, key)) {
free(rsa);
RSA_free(key);
return 0;
} RSA_free(key);
if (rsa_size/3 * 4 >= buf_size) { /* 结果的 Base64 编码后长度大于 buf_size, 等于也错误(后面需要放 '\0' 的位置) */
free(rsa);
return 0; }
b64_encode(rsa, rsa_size, buf);
free(rsa);
return 1;
}
可是找遍 PyCrypto, 楞是没有看到怎么实现 PEM_read_bio_RSAPrivateKey 这样从一个 PEM 格式的私钥文件里加载的功能。然后去看哪些基于 PyCrypto 包装的其他的包,比如 ezPyCrypto, Keyczar(这还是 google 发布的),包括 mail-list 上提供的 patch.... 这些似乎倒是可以 load key 了,可缺省好像也并没有对 NID_MD5 的支持, 绝望~~~~
于是抱着试试的心态用 ctypes 直接去调 libcrypto——以前只是在 PyS60 上玩票似的用过 ctypes,以及在 Win32 下用过,而且那时候 ctypes 还不太成熟——结果发现 python2.5 的 ctypes 竟如此的好用:
import ctypesimport base64
crypto_handler = ctypes.cdll.LoadLibrary("/usr/lib/libcrypto.so")
BIO_new_file = crypto_handler.BIO_new_file
PEM_read_bio_RSAPrivateKey = crypto_handler.PEM_read_bio_RSAPrivateKey
RSA_size = crypto_handler.RSA_size
RSA_sign = crypto_handler.RSA_sign
BIO_free = crypto_handler.BIO_free
RSA_free = crypto_handler.RSA_freeNID_md5 = 4
bio = BIO_new_file("/yourpathfile.key", "r")
key = PEM_read_bio_RSAPrivateKey(bio, 0, 0, 0)
r = BIO_free(bio)
if r != 1:
# break here print 'BIO_free error'
rsa_size = RSA_size(key)
rsa = ctypes.create_string_buffer(rsa_size)sign_size = ctypes.create_string_buffer(4)
message = "foobar"
if 1 != RSA_sign(NID_md5, message, len(message), rsa, sign_size, key):
print 'RSA_sign error'RSA_free(key)
print base64.urlsafe_b64encode(rsa.raw)
Topic:
技术
最新评论