Chinaunix首页 | 论坛 | 博客
  • 博客访问: 380018
  • 博文数量: 56
  • 博客积分: 1449
  • 博客等级: 中尉
  • 技术积分: 822
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-08 10:24
文章分类

全部博文(56)

文章存档

2014年(7)

2012年(13)

2011年(10)

2010年(26)

分类:

2010-11-23 22:23:27

 

转换矩阵常量定义. des_constants.h
#ifndef _DES_CONSTANTS
#define _DES_CONSTANTS

/* 任意Ki和Kj对应的密钥所需要进行的移位之间没有关系,所以修改这里的矩阵*/ 

const unsigned char rotate[] = {

   1, 2, 5, 7, 9, 11, 13, 15,
   17, 19, 21, 23, 25, 27, 29, 30
};

const unsigned char trans_c0 [] = {
    57, 49, 41, 33, 25, 17, 9 ,
    1 , 58, 50, 42, 34, 26, 18,
    10, 2 , 59, 51, 43, 35, 27,
    19, 11, 3 , 60, 52, 44, 36
};

const unsigned char trans_d0[] = {
    63, 55, 47, 39, 31, 23, 15,
    7 , 62, 54, 46, 38, 30, 22,
    14, 6 , 61, 53, 45, 37, 29,
    21, 13, 5 , 28, 20, 12, 4
};

const unsigned char trans_combine[] = {
    14, 17, 11, 24, 1 , 5 ,
    3 , 28, 15, 6 , 21, 10,
    23, 19, 12, 4 , 26, 8 ,
    16, 7 , 27, 20, 13, 2 ,
    41, 52, 31, 37, 47, 55,
    30, 40, 51, 45, 33, 48,
    44, 49, 39, 56, 34, 53,
    46, 42, 50, 36, 29, 32
};

const unsigned char IP[] = {
    58, 50, 42, 34, 26, 18, 10, 2 ,
    60, 52, 44, 36, 28, 20, 12, 4 ,
    62, 54, 46, 38, 30, 22, 14 ,6 ,
    64, 56, 48, 40, 32, 24, 16, 8 ,
    57, 49, 41, 33, 25, 17, 9 , 1 ,
    59, 51, 43, 35, 27, 19, 11, 3 ,
    61, 53, 45, 37, 29, 21, 13, 5 ,
    63, 55, 47, 39, 31, 23, 15, 7
};

const unsigned char Eselect[] = {
    32, 1 , 2 , 3 , 4 , 5 ,
    4 , 5 , 6 , 7 , 8 , 9 ,
    8 , 9 , 10, 11, 12, 13,
    12, 13, 14, 15, 16, 17,
    16, 17, 18, 19, 20, 21,
    20, 21, 22, 23, 24, 25,
    24, 25, 26, 27, 28, 29,
    28, 29, 30, 31, 32, 1
};

const unsigned char inverseP[] = {
    16, 7 , 20, 21,
    29, 12, 28, 17,
    1 , 15, 23, 26,
    5 , 18, 31, 10,
    2 , 8 , 24, 14,
    32, 27, 3 , 9 ,
    19, 13, 30, 6 ,
    22, 11, 4 , 25
};

const unsigned char reverseIP[] = {
    40, 8 , 48, 16, 56, 24, 64, 32,
    39, 7 , 47, 15, 55, 23, 63, 31,
    38, 6 , 46, 14, 54, 22, 62, 30,
    37, 5 , 45, 13, 53, 21, 61, 29,
    36, 4 , 44, 12, 52, 20, 60, 28,
    35, 3 , 43, 11, 51, 19, 59, 27,
    34, 2 , 42, 10, 50, 18, 58, 26,
    33, 1 , 41, 9 , 49, 17, 57, 25
};

const unsigned char s_box[][64] = {
    {
        14, 4 , 13, 1 , 2 , 15, 11, 8 , 3 , 10, 6 , 12, 5 , 9 , 0 , 7 ,
        0 , 15, 7 , 4 , 14, 2 , 13, 1 , 10, 6 , 12, 11, 9 , 5 , 3 , 8 ,
        4 , 1 , 14, 8 , 13, 6 , 2 , 11, 15, 12, 9 , 7 , 3 , 10, 5 , 0 ,
        15, 12, 8 , 2 , 4 , 9 , 1 , 7 , 5 , 11, 3 , 14, 10, 0 , 6 , 13
    },
    {
        15, 1 , 8 , 14, 6 , 11, 3 , 4 , 9 , 7 , 2 , 13, 12, 0 , 5 , 10,
        3 , 13, 4 , 7 , 15, 2 , 8 , 14, 12, 0 , 1 , 10, 6 , 9 , 11, 5 ,
        0 , 14, 7 , 11, 10, 4 , 13, 1 , 5 , 8 , 12, 6 , 9 , 3 , 2 , 15,
        13, 8 , 10, 1 , 3 , 15, 4 , 2 , 11, 6 , 7 , 12, 0 , 5 , 14, 9
    },
    {
        10, 0 , 9 , 14, 6 , 3 , 15, 5 , 1 , 13, 12, 7 , 11, 4 , 2 , 8 ,
        13, 7 , 0 , 9 , 3 , 4 , 6 , 10, 2 , 8 , 5 , 14, 12, 11, 15, 1 ,
        13, 6 , 4 , 9 , 8 , 15, 3 , 0 , 11, 1 , 2 , 12, 5 , 10, 14, 7 ,
        1 , 10, 13, 0 , 6 , 9 , 8 , 7 , 4 , 15, 14, 3 , 11, 5 , 2 , 12
    },
    {
        7 , 13, 14, 3 , 0 , 6 , 9 , 10, 1 , 2 , 8 , 5 , 11, 12, 4 , 15,
        13, 8 , 11, 5 , 6 , 15, 0 , 3 , 4 , 7 , 2 , 12, 1 , 10, 14, 9 ,
        10, 6 , 9 , 0 , 12, 11, 7 , 13, 15, 1 , 3 , 14, 5 , 2 , 8 , 4 ,
        3 , 15, 0 , 6 , 10, 1 , 13, 8 , 9 , 4 , 5 , 11, 12, 7 , 2 , 14
    },
    {
        2 , 12, 4 , 1 , 7 , 10, 11, 6 , 8 , 5 , 3 , 15, 13, 0 , 14, 9 ,
        14, 11, 2 , 12, 4 , 7 , 13, 1 , 5 , 0 , 15, 10, 3 , 9 , 8 , 6 ,
        4 , 2 , 1 , 11, 10, 13, 7 , 8 , 15, 9 , 12, 5 , 6 , 3 , 0 , 14,
        11, 8 , 12, 7 , 1 , 14, 2 , 13, 6 , 15, 0 , 9 , 10, 4 , 5 , 3
    },
    {
        12, 1 , 10, 15, 9 , 2 , 6 , 8 , 0 , 13, 3 , 4 , 14, 7 , 5 , 11,
        10, 15, 4 , 2 , 7 , 12, 9 , 5 , 6 , 1 , 13, 14, 0 , 11, 3 , 8 ,
        9 , 14, 15, 5 , 2 , 8 , 12, 3 , 7 , 0 , 4 , 10, 1 , 13, 11, 6 ,
        4 , 3 , 2 , 12, 9 , 5 , 15, 10, 11, 14, 1 , 7 , 6 , 0 , 8 , 13
    },
    {
        4 , 11, 2 , 14, 15, 0 , 8 , 13, 3 , 12, 9 , 7 , 5 , 10, 6 , 1 ,
        13, 0 , 11, 7 , 4 , 9 , 1 , 10, 14, 3 , 5 , 12, 2 , 15, 8 , 6 ,
        1 , 4 , 11, 13, 12, 3 , 7 , 14, 10, 15, 6 , 8 , 0 , 5 , 9 , 2 ,
        6 , 11, 13, 8 , 1 , 4 , 10, 7 , 9 , 5 , 0 , 15, 14, 2 , 3 , 12
    },
    {
        13, 2 , 8 , 4 , 6 , 15, 11, 1 , 10, 9 , 3 , 14, 5 , 0 , 12, 7 ,
        1 , 15, 13, 8 , 10, 3 , 7 , 4 , 12, 5 , 6 , 11, 0 , 14, 9 , 2 ,
        7 , 11, 4 , 1 , 9 , 12, 14, 2 , 0 , 6 , 10, 13, 15, 3 , 5 , 8 ,
        2 , 1 , 14, 7 , 4 , 10, 8 , 13, 15, 12, 9 , 0 , 3 , 5 , 6 , 11
    }
};
#endif

加密模块 des.c文件,仅需要对外提供一个加密解密的函数接口即可.随意写的...没有严格的参数检查等机制...

#include
#include
#include
#include "des_constants.h"
#include "des_core.h"


void print_binary(unsigned char *b, int bits)
{
    int i;
    for(i = 0; i < bits; i++) {
        printf("%d", b[i]);
        if(!((i + 1) % 8))
            printf(" ");
    }
    printf("\n");
}

static int init_cd(unsigned char *c0, unsigned char *d0, unsigned char *key)
{
    int i;
    for(i = 0; i < 28; i++) {
        c0[i] = key[trans_c0[i] - 1];
        d0[i] = key[trans_d0[i] - 1];
    }
#ifdef __DEBUG__
    printf("c0:\t");
    print_binary(c0, 28);
    printf("d0:\t");
    print_binary(d0, 28);
#endif
}

static void gen_subkey(unsigned char *c, unsigned char *d,\
             unsigned char *subkey, int no_recursive)
{
    int i;
    int real_idx;   
    int cur_rotate_bits = rotate[i];
//    for(i = 0; i < no_recursive; i++)
//       cur_rotate_bits += rotate[i];
    for(i = 0; i < 48; i++) {
        real_idx = trans_combine[i];
        if(real_idx <= 28) {
            real_idx += cur_rotate_bits - 1;
            real_idx %= 28;
            subkey[i] = c[real_idx];
        } else {
            real_idx += cur_rotate_bits - 1;
            real_idx %= 28;
            subkey[i] = d[real_idx];
        }
        if(subkey[i] > 1) {
            printf("\nBUGGY: subkey[%d] = %d\t", i, subkey[i]);
            printf("d[%d] = %d\n", real_idx, d[real_idx]);
            exit(-1);
        }
    }
#ifdef __DEBUG__
    printf("key%d\t", no_recursive);
    print_binary(subkey, 48);
#endif
}

static void init_trans_IP(const unsigned char *plain_text, unsigned char *l, \
                        unsigned char *r)
{
    int i;
    for(i = 0; i < 32; i++) {
        l[i] = plain_text[IP[i] - 1];
        r[i] = plain_text[IP[i+32] - 1];
#ifdef __DEBUG__
        if(l[i] > 1 || r[i] > 1) {
            printf("BUGGY: %s, %d", __FUNCTION__, __LINE__);
            exit(-1);
        }
#endif
    }
#ifdef __DEBUG__
    printf("L0:\t");
    print_binary(l, 32);
    printf("\nR0:\t");
    print_binary(r, 32);
#endif
}   

static inline void gen_select_tmp48(unsigned char *r, unsigned char *tmp)
{
    int i;
    for(i = 0; i < 48; i++)
        tmp[i] = r[Eselect[i] - 1];
#ifdef __DEBUG__
    printf("select:\t");
    print_binary(tmp, 48);
#endif
}
static inline void mod2_add(unsigned char *tmp, unsigned char *subkey, int bits)
{
    int i;
    for(i = 0; i < bits; i++)
        tmp[i] ^= subkey[i];
#ifdef __DEBUG__
    printf("add:\t");
    print_binary(tmp, bits);
#endif
}

static void replace_funcS(unsigned char *tmp, unsigned char *out)
{
    int row, col;
    int i, j;
    int subout;
    for(i = 0; i < 8; i++) {
        row = (tmp[i * 6] << 1) + tmp[i * 6 + 5];
        col = (tmp[i * 6 + 1] << 3) + (tmp[i * 6 + 2] << 2)
            + (tmp[i * 6 + 3] << 1) + tmp[i * 6 + 4];
        subout = s_box[i][row*16 + col];
        for(j = 0; j < 4; j++)
            out[i * 4 + j] = (subout & (1 << (3 -j))) >> (3 - j);
    }
#ifdef __DEBUG__
    printf("s_out:\t");
    print_binary(out, 32);
#endif
}

static inline void inverse_P(unsigned char *res)
{
    unsigned char tmp[32];
    int i;
    memcpy(tmp, res, 32);
    for(i = 0; i < 32; i++)
        res[i] = tmp[inverseP[i] -1];
#ifdef __DEBUG__
    printf("P:\t");
    print_binary(res, 32);
#endif
}

static inline void reverse_IP(const unsigned char *l, const unsigned char *r, \
                    unsigned char *encrypt)
{
    int i;
    for(i = 0; i < 64; i++) {
        if(reverseIP[i] <= 32)
            encrypt[i] = l[(reverseIP[i] - 1) % 32];
        else
            encrypt[i] = r[(reverseIP[i] - 1) % 32];
        if(encrypt[i] > 1) {
            printf("BUGGY encrypt[%d] = %d\n",i, encrypt[i] );
            printf("r[%d] = %d\n", reverseIP[i] - 1, \
                         l[reverseIP[i] - 1]);
            exit(1);
        }
    }
}

static void des_core(unsigned char *plain_text, unsigned char *key, \
                unsigned char *encrypt, int decode)
{
    unsigned char c[28];
    unsigned char d[28];
    unsigned char subkey[48];
    unsigned char tmp[48];
    unsigned char s_out[32];
    unsigned char *l, *r, *tmpp;
    int i;
    int recursive, step;
    if(!decode) {
        recursive = 1;
        step = 1;
    } else {
        recursive = 16;
        step = -1;
    }   
    l = (unsigned char *)malloc(sizeof(unsigned char) * 32);
    r = (unsigned char *)malloc(sizeof(unsigned char) * 32);
    if(!l || !r) {
        printf("OOM: malloc failed!\n");
        exit(-2);
    }
    init_cd(c, d, key);
    init_trans_IP(plain_text, l, r);
    for(i = 0; i < 16; i++) {
       
        gen_subkey(c, d, subkey, recursive);
        recursive += step;

        gen_select_tmp48(r, tmp);
        mod2_add(tmp, subkey, 48);
        replace_funcS(tmp, s_out);
        inverse_P(s_out);   
       
        mod2_add(l, s_out, 32);
        if(i != 15) {
            tmpp = r;
            r = l;
            l = tmpp;
        }
#ifdef __DEBUG__
        printf("L%d:\t", i+1);
        print_binary(l, 32);
        printf("R%d:\t", i+1);
        print_binary(r, 32);
        printf("\n");
#endif
    }
    reverse_IP(l, r, encrypt);
}
       
void des_encrypt(unsigned char *plain, unsigned char *key, \
                        unsigned char * encrypt)
{
    des_core(plain, key, encrypt, 0);
}
void des_decode(unsigned char *encrypt, unsigned char *key, \
                        unsigned char *plain)
{
    des_core(encrypt, key, plain, 1);
}

加密解密接口函数头文件, des_core.h
#ifndef _DES_CORE_H
#define _DES_CORE_H

void des_encrypt(unsigned char *, unsigned char *, unsigned char *);
void des_decode(unsigned char *, unsigned char *, unsigned char *);
#endif


加密解密程序主函数encrypt.c文件, 提供一些选项...  help函数没有实现...  没有实现密钥选择...提供一个选项, 从某文件读取或者直接输入即可... 懒得烦了...嘿嘿...
#include
#include
#include
#include "des_core.h"
#include
#define BUFSIZE 4096

static inline void str2bin64(unsigned char *str, unsigned char *bin64)
{
    int i, j;
    for(i = 0; i < 8; i++) {   
        for(j = 0; j < 8; j++) {
            bin64[i*8 + j] = str[i] >> (8 - 1 - j);
            str[i] &= ~(1 << (8 -1 - j));
        }
    }
}

static void output_bin64(FILE *out, unsigned char *bin64, int bytes)
{
    int i, j;
    unsigned char output[8];
    bzero(output, sizeof(output));
    for(i = 0; i < bytes; i++) {
        for(j = 0; j < 8; j++)
            output[i] += bin64[i*8 + j] << (8 - 1 - j);
    }
    write(fileno(out), output, 8);
}

typedef void (*core_fn) (unsigned char *, unsigned char *, unsigned char *);

static void __core_text_en_de(FILE *in, FILE *out, unsigned char *key, int en)
{
    unsigned char buf[BUFSIZE];
    unsigned char bin64[64];
    unsigned char res[64];
    unsigned char *ptr;
    int i, j;
    int left;
    core_fn fn;
    if(en)
        fn = des_encrypt;
    else
        fn = des_decode;
    while((left = read(fileno(in), buf, BUFSIZE)) > 0) {
        ptr = buf;
        while(left >= 8) {
            str2bin64(ptr, bin64);
            (*fn)(bin64, key, res);
            output_bin64(out, res, 8);
            left -= 8;
            ptr += 8;
        }
        if(left) {
            int i;
            for(i = left; i < 8; i++)
                ptr[i] = 0;
            str2bin64(ptr, bin64);
            des_encrypt(bin64, key, res);
            output_bin64(out, res, 8);
            left = 0;
        }
    }
}
void text_encrypt(FILE *in, FILE *out, unsigned char *key)
{
    __core_text_en_de(in, out, key, 1);
}
void text_decode(FILE *in, FILE *out, unsigned char *key)
{
    __core_text_en_de(in, out, key, 0);
}

static FILE *open_file(const char *filepath, const char *mode)
{
    FILE *fp;
    fp = fopen(filepath, mode);
    if(!fp) {
        printf("open file for %s failed!\n", filepath);
        exit(-1);
    }
    return fp;
}
#define open_file_r(filepath) \
    open_file(filepath, "r")

#define open_file_w(filepath) \
    open_file(filepath, "w")

int main(int argc, char *argv[])
{
    int en;
    char c;
    opterr = 0;
    FILE *in = NULL;
    FILE *out = NULL;
    while((c = getopt(argc, argv, "hedi:o:")) != -1) {
        switch(c) {
        case 'h':                      //print help
            print_help();
            exit(0);
        case 'e':
            en = 1;                  // encrypt
            break;
        case 'd':
            en = 0;                 //decode
            break;
        case 'i':
            in = open_file_r(optarg);   // input of plain or encrypted file
            break;
        case 'o':
            out = open_file_w(optarg);   // output of plain text or encrypted file
            break;
        default:
            printf("Unrecognized options: %c", c);
            exit(-1);
        }
    }
    unsigned char key[64];
    unsigned char key_str[] = "abcdefgh";
    if(!in)
        in = stdin;
    if(!out)
        out = stdout;
    str2bin64(key_str, key);
    if(en)
        text_encrypt(in, out, key);
    else
        text_decode(in, out, key);
    return 0;
}


阅读(1547) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~