使用M2Crypto库
需要安装M2Crypto库
# -*- coding: UTF-8 -*-
import M2Crypto
from Crypto.PublicKey import RSA
import base64
import sys
#私钥加密,公钥解密
def pri_encrypt(msg, file_name):
rsa_pri = M2Crypto.RSA.load_key(file_name)
ctxt_pri = rsa_pri.private_encrypt(msg, M2Crypto.RSA.pkcs1_padding) #这里的方法选择加密填充方式,所以在解密的时候 要对应。
ctxt64_pri = ctxt_pri.encode('base64') #密文是base64 方便保存 encode成str
print ('密文:%s'% ctxt64_pri)
return ctxt64_pri
def pub_decrypt_with_pubkeyfile(msg, file_name):
rsa_pub = M2Crypto.RSA.load_pub_key(file_name)
pub_decrypt(msg, rsa_pub)
def pub_decrypt_with_pubkeystr(msg, pub_key):
#将pub_key转成bio对象,再将bio对象转换成公钥对象
bio = M2Crypto.BIO.MemoryBuffer(pub_key)
rsa_pub = M2Crypto.RSA.load_pub_key_bio(bio)
pub_decrypt(msg, rsa_pub)
def pub_decrypt(msg, rsa_pub):
ctxt_pri = msg.decode("base64") # 先将str转成base64
maxlength = 128
output = ''
while ctxt_pri:
input = ctxt_pri[:128]
ctxt_pri = ctxt_pri[128:]
out = rsa_pub.public_decrypt(input, M2Crypto.RSA.pkcs1_padding) #解密
output = output + out
print('明文:%s'% output)
if __name__ == "__main__":
prikey_file = './rsa/rsa_private_key.pem'
pubkey_file = './rsa/rsa_public_key.pem'
msg = 'Test String.'
primsg = pri_encrypt(msg, prikey_file)
pub_decrypt(primsg, pubkey_file)
使用C语言的动态库
decrypt.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
void decrypt(char *pristr, char *pubkey, int padding, char *pub_str)
{
BIO *bp;
EVP_PKEY *pkey;
int crypted_len, n;
size_t data_len;
char *data, *dest_p, *p, *last, *decrypt_buf, *dest;
char buf[128];
bp = BIO_new_mem_buf((void *)pubkey, -1);
pkey = PEM_read_bio_PUBKEY(bp, NULL, NULL, NULL);
BIO_free(bp);
if (!pkey) {
fprintf(stderr, "get public key error\n");
return;
}
crypted_len = EVP_PKEY_size(pkey);
decrypt_buf = malloc(crypted_len + 1);
if (!decrypt_buf) {
fprintf(stderr, "decrypt_buf, malloc error\n");
return;
}
base64_decode(pristr, (unsigned char **)&data, &data_len);
dest = malloc(data_len);
if (!dest) {
fprintf(stderr, "dest, malloc error\n");
free(decrypt_buf);
return;
}
dest_p = dest;
p = data;
last = data + data_len;
do {
n = last - p;
if (n > 128) {
n = 128;
}
bzero(buf, sizeof(buf));
bzero(decrypt_buf, sizeof(decrypt_buf));
memcpy(buf, p, n);
p += n;
crypted_len = RSA_public_decrypt(n, (unsigned char *)buf, decrypt_buf, pkey->pkey.rsa, padding);
if (crypted_len != -1) {
memcpy(dest_p, decrypt_buf, crypted_len);
dest_p += crypted_len;
}
} while (last - p > 0);
*dest_p = 0;
strcpy(pub_str, dest);
free(decrypt_buf);
free(dest);
free(data);
}
size_t calc_decode_len(const char* b64input) {
size_t len = strlen(b64input), padding = 0;
if (b64input[len - 1] == '=' && b64input[len - 2] == '=') {
padding = 2;
} else if (b64input[len - 1] == '=') {
padding = 1;
}
return (size_t) len * 0.75 - padding;
}
int base64_decode(char *b64message, unsigned char **buffer, size_t *len) {
BIO *bio, *b64;
int decode_len = calc_decode_len(b64message);
*buffer = malloc(decode_len);
if (!*buffer) {
fprintf(stderr, "buffer, malloc error\n");
return -1;
}
bio = BIO_new_mem_buf(b64message, -1);
b64 = BIO_new(BIO_f_base64());
bio = BIO_push(b64, bio);
BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL);
*len = BIO_read(bio, *buffer, strlen(b64message));
BIO_free_all(bio);
if (*len != decode_len) {
return -1;
}
return 0;
}
decrypt.h
#ifndef __DECRYPT_H__
#define __DECRYPT_H__
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
void decrypt(char* pristr, char* pubkey, int padding, char* pubstr);
#endif
编译,生成一个动态库文件
gcc -Wall -fpic -shared -lcrypto decrypt.c -o libdec.so
写一个测试文件进行测试,main.c
#include "decrypt.h"
#include <stdio.h>
int main()
{
//公钥
char *pkey_str = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2kcrRvxURhFijDoPpqZ/IgPlA\ngppkKrek6wSrua1zBiGTwHI2f+YCa5vC1JEiIi9uw4srS0OSCB6kY3bP2DGJagBo\nEgj/rYAGjtYJxJrEiTxVs5/GfPuQBYmU0XAtPXFzciZy446VPJLHMPnmTALmIOR5\nDddd1Zklod9IQBMjjwIDAQAB\n-----END PUBLIC KEY-----";
//用私钥加密过的字符串
char *pri_str = "YFSGlJTpNYakrZuZqZ55dcA5mVUb/JQBr3hdDjODsAVSdoVVytIagk9Wt0CD/uX+7jGL9pqev8/u0I0ZBKEmz5huXp8TdZSnskCZ7GTeHNW0VPJcW8OcBxAValA0jQSv2mBP+tc1r6mdvf66GEzhvgBfTnp3Sp7V3dijJ9bNstIDyrGm/BlByhcMr3UqXjTFJaui6t5TxvZhCuSV9sg+xVVA+sR3uFI78b5lKomg5Vu31EBZvXASlFfaOc4StltRUH2aSiRqjnbXe8dlRZO0Ih44htYs2QfehzeQnPHtTwNHUvtVIVcIdI/7j9yfy5es13QeIgfKghY/ENUnB2V7iA==";
char decrypted_buf[10240];
decrypt(pri_str, pkey_str, 1, decrypted_buf);
printf("%s", decrypted_buf);
return 0;
}
编译,测试:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:'pwd'
gcc main.c -o test -L./ -ldec
./test
[zhangshibo@tuyoo so_test]${"order_id_com":"2013061805870589","amount":"0.10","account":"test","order_id":"2013061800002115","result":"success","user_id":"0"}
在python中使用libdec.so
注意,需要安装cffi,然后用pypy运行
test.py
import os
from cffi import FFI
path = os.path.split(os.path.realpath(__file__))[0]
ffi = FFI()
#引入动态库
lib = ffi.dlopen(path + "/libdec.so")
print('Loaded lib {0}'.format(lib))
#函数声明,类似于C的.h文件
ffi.cdef(
'''
void decrypt(char* pristr, char* pubkey, int padding, char* pubstr);
int printf(const char* format, ...);
'''
)
#公钥
pkey_str = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC2kcrRvxURhFijDoPpqZ/IgPlA
gppkKrek6wSrua1zBiGTwHI2f+YCa5vC1JEiIi9uw4srS0OSCB6kY3bP2DGJagBo
Egj/rYAGjtYJxJrEiTxVs5/GfPuQBYmU0XAtPXFzciZy446VPJLHMPnmTALmIOR5
Dddd1Zklod9IQBMjjwIDAQAB
-----END PUBLIC KEY-----'''
#用私钥加密过的字符串
pri_str = "klzAd6Qu87M/0GdkmmeJbyk/NKuIIRS/M/4GpckMNfe4jwjBc9w38LExpYVvJZ5RKkr2y9Wuj6cZsThqAM0ZDcFZ2Ew2csRZlMnc9kD/yqHHMb0fb6KL3g7DZ3sRAhAIT2MkTDHOVKctxrc5Qcn8Ie2IX1Xgz7G+yvn0j1VYc3xGUbbCxxPjb3MTuDUDFbElPNq98dQufrcFUBsXwVdQJv6+GwE+7N/IJffPA6TNv3aB+AUe7sc/lbKOywxCSb0+rxPkb0mcT6q5O0S1bRIvZqtxQJn0HydqmFYPBYr9X2lzkgGIwZL8oX6vb2YVNHRPoCxKh+10TewAOOlUggbTfA=="
#申请C风格的数组
pub_str = ffi.new("char[]", 10240)
lib.decrypt(pri_str, pkey_str, 1, pub_str)
print pub_str
lib.printf("%s\n", pub_str)
#转换成Python可用的字符串
pystr = ffi.string(pub_str)
print pystr