python 封装3des加解密库

最近项目需要用到3des加解密,python写的3des加密速度太慢,所以考虑用c/c++完成,项目是在linux部署,而linux中openssl中包括3des加密,而且自己写的肯定没有大神们都用的openssl好用,所以决定使用openssl中的加密模块。

起初,是想用python直接调用,但是需要加载openssl的so库,并且部署的机器上还得安装openssl-devel,比较麻烦。而且3des只是openssl其中一个模块,没必要把整个openssl都引用,所以决定把其中的3des模块摘出来,编译成so库。最后发现,还是编译成python可识别的c扩展比较方便。本文记录在其中遇到的问题。

第一步:把3des模块,从openssl中摘出来,比较简单需要一点耐心。3des模块,把这5个函数摘出来即可:DES_decrypt3, DES_encrypt3, DES_encrypt2, DES_set_key,DES_ecb3_encrypt。要把引用的宏定义头文件挑出来,基本都在这4个头文件中:des.h,e_os2.h,des_locl.h,opensslconf.h。如果有漏掉的,去找出来就行。在这几个头文件没用的函数定义,编译的时候谁出错,削了谁,注释掉就行。千万别自己写宏,说不准那就报错了。

第二步:新建c文件,引用Python.h,编写几个对Python函数接口,具体的python c扩展,可以去百度一下,这里不在赘述。上代码:

#################des3.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dlfcn.h>
#include <time.h>

#include "des3.h"
#include "Python.h"

#define LEN_OF_KEY 24

int get_rand_key(unsigned char *pKey, int len)//unsigned char *pKeyEncrpt,
{
    int i = 0;
    while (i < len)
    {
        pKey[i] = (unsigned char)(rand()%256);
        i++;
    }
    return 0;
}

int des_encrypt_3(unsigned char *data, unsigned char *k, unsigned char *en_data, int data_len)
{
    if (data == NULL || k == NULL ||en_data == NULL)
        return 1;
    unsigned char *src = NULL; /* 补齐后的明文 */

    int ch = 0;
    int len = (data_len + 7)/8*8;
    src = (unsigned char *)malloc(len+1);
    if (NULL == src)
        return 2;
    /* 构造补齐后的加密内容 */
    memset(src, ch, len+1);
    memcpy(src, data, data_len);
    //memcpy(src + data_len, ch, 8 - data_rest);

    /* 密钥置换 */
    unsigned char block_key[9];
    DES_key_schedule ks,ks2,ks3;

    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, k + 0, 8);
    DES_set_key((DES_cblock*)block_key, &ks);
    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, k + 8, 8);
    DES_set_key((DES_cblock*)block_key, &ks2);
    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, k + 16, 8);
    DES_set_key((DES_cblock*)block_key, &ks3);

    unsigned char in[8];
    unsigned char out[8];
    int count = 0;
    int i = 0;
    count = len / 8;
    for (i = 0; i < count; i++)
    {
        memset(in, 0, 8);
        memset(out, 0, 8);
        memcpy(in, src + 8 * i, 8);
        /* 加密 */
        DES_ecb3_encrypt((DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_ENCRYPT);
        /* 将加密的内容拷贝到加密后的数据 */
        memcpy(en_data + 8 * i, out, 8);
    }

    if (NULL != src)
    {
        free(src);
        src = NULL;
    }

    return 0;
}

int des_decrypt_3(unsigned char *data, unsigned char *k, unsigned char *de_data, int data_len)
{
    if (data == NULL || k == NULL ||de_data == NULL)
        return 1;
    unsigned char *src = NULL; /* 补齐后的明文 */

    int ch = 0;
    int len = (data_len + 7)/8*8;
    src = (unsigned char *)malloc(len+1);
    if (NULL == src)
        return 2;

    /* 构造补齐后的加密内容 */
    memset(src, ch, len+1);
    memcpy(src, data, data_len);
    //memcpy(src + data_len, ch, 8 - data_rest);

    /* 密钥置换 */
    unsigned char block_key[9];
    DES_key_schedule ks,ks2,ks3;

    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, k + 0, 8);
    DES_set_key((DES_cblock*)block_key, &ks);
    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, k + 8, 8);
    DES_set_key((DES_cblock*)block_key, &ks2);
    memset(block_key, 0, sizeof(block_key));
    memcpy(block_key, k + 16, 8);
    DES_set_key((DES_cblock*)block_key, &ks3);

    unsigned char in[8];
    unsigned char out[8];
    int count = 0;
    int i = 0;

    count = len / 8;
    for (i = 0; i < count; i++)
    {
        memset(in, 0, 8);
        memset(out, 0, 8);
        memcpy(in, src + 8 * i, 8);
        /* 加密 */
        DES_ecb3_encrypt((DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_DECRYPT);
        /* 将加密的内容拷贝到加密后的数据 */
        memcpy(de_data + 8 * i, out, 8);
    }

    if (NULL != src)
    {
        free(src);
        src = NULL;
    }

    return 0;
}

static PyObject * Des3_get_rand_key(PyObject *self, PyObject *args)
{
    unsigned char *key;
    int len;
    if (!PyArg_ParseTuple(args, "si", &key, &len))
    {
        return NULL;
    }
    return (PyObject *)Py_BuildValue("i", get_rand_key(key, len));
}

static PyObject * Des3_des_encrypt_3(PyObject *self, PyObject *args)
{
    unsigned char *data;
    int data_len;
    unsigned char *key;
    int key_len;
    int en_len;
    unsigned char *en_data;
    PyObject *retval;
    if (!PyArg_ParseTuple(args, "z#z#z#", &data, &data_len, &key, &key_len, &en_data, &en_len))
    {
        return NULL;
    }
    retval = (PyObject *)Py_BuildValue("i", des_encrypt_3(data, key, en_data, data_len));
    return retval;
}

static PyObject * Des3_des_decrypt_3(PyObject *self, PyObject *args)
{
    unsigned char *data;
    int data_len;
    unsigned char *key;
    int key_len;
    int de_len;
    unsigned char *de_data;
    PyObject *retval;
    if (!PyArg_ParseTuple(args, "z#z#z#", &data, &data_len,  &key, &key_len, &de_data, &de_len))
    {
        return NULL;
    }

    retval = (PyObject *)Py_BuildValue("i", des_decrypt_3(data, key, de_data, data_len));
    return retval;
}

int test(void)
{
    unsigned char *data = "FVmJTZAFHAEJRF1gzXVkLWFM%2FXT4DIgY9ATJQNgU7C3VSb1chBzIOUVMADjIHb1YaBRBbR"; /* 明文 */
//    FILE *fp = NULL;
//    fp = fopen("/opt/encrypt_transport/data/zx_zx010002_210d_20160509041117_000563c1", "r");
//    fseek(fp,0,SEEK_SET);
//    char * data = (char *)malloc(4097);
//    while (!feof(fp)){
//    memset(data, 0, 4097);
//    fread(d

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值