1. 程式人生 > >使用openssl庫實現des,3des加密

使用openssl庫實現des,3des加密

說明:最近工作中用到3des(Triple DES)加密,網上的資料大部分都是介紹演算法原理,沒什麼興趣,man了一下查到openssl提供DES_ecb3_encrypt方法,正合我意!提示:openssl庫支援很多加密演算法哦,如:AES/DES/MD5/RSA...,而且很輕鬆的支援其他平臺,我就在winXP下安裝了openssl並在VC中設定標頭檔案目錄及庫檔案目錄,用來是用openssl庫。   程式碼下載:linux平臺程式碼:http://pickup.mofile.com/2320229012095812windows平臺程式碼:http://pickup.mofile.com/7098802825381299具體使用時需要注意des演算法的加密模式、金鑰長度、補齊方式,我這裡採用3des的ECB方式、24位金鑰(不足右補0)、內容長度以8位元組切分,不能被8整除的末尾部分,根據長度不足8位元組的部分,填充0x01-0x08

今天修正了一下程式碼裡面一個常識性錯誤:des加密金鑰也是8位來處理的,所以在金鑰置換時只取8位。希望沒有誤導大家,我同時更新了原始碼下載地址好程式碼,標準的位數不足應該都補0x00把另外,如何得到全部的加密後密文的16進位制字元?

程式碼如下:

  1. #include <stdio.h> 
  2. #include <stdlib.h> 
  3. #include <string.h> 
  4. #include <openssl/des.h> 
  5. /************************************************************************ 
     
  6. ** 本例採用:  
  7. ** 3des-ecb加密方式;  
  8. ** 24位金鑰,不足24位的右補0x00;  
  9. ** 加密內容8位補齊,補齊方式為:少1位補一個0x01,少2位補兩個0x02,...  
  10. ** 本身已8位對齊的,後面補八個0x08。  
  11. ************************************************************************/
  12. int main(void)   
  13. {   
  14.     int docontinue = 1;   
  15.     char *data = "hello world!"/* 明文 */
  16.     int data_len;   
  17.     int data_rest;   
  18.     unsigned char ch;   
  19.     unsigned char *src = NULL; /* 補齊後的明文 */
  20.     unsigned char *dst = NULL; /* 解密後的明文 */
  21.     int len;   
  22.     unsigned char tmp[8];   
  23.     unsigned char in[8];   
  24.     unsigned char out[8];   
  25.     char *k = "01234567899876543210"/* 原始金鑰 */
  26.     int key_len;   
  27.     #define LEN_OF_KEY 24 
  28.     unsigned char key[LEN_OF_KEY]; /* 補齊後的金鑰 */
  29.     unsigned char block_key[9];   
  30.     DES_key_schedule ks,ks2,ks3;   
  31.     /* 構造補齊後的金鑰 */
  32.     key_len = strlen(k);   
  33.     memcpy(key, k, key_len);   
  34.     memset(key + key_len, 0x00, LEN_OF_KEY - key_len);   
  35.     /* 分析補齊明文所需空間及補齊填充資料 */
  36.     data_len = strlen(data);   
  37.     data_rest = data_len % 8;   
  38.     len = data_len + (8 - data_rest);   
  39.     ch = 8 - data_rest;   
  40.     src = (unsigned char *)malloc(len);   
  41.     dst = (unsigned char *)malloc(len);   
  42.     if (NULL == src || NULL == dst)   
  43.     {   
  44.         docontinue = 0;   
  45.     }   
  46.     if (docontinue)   
  47.     {   
  48.         int count;   
  49.         int i;   
  50.         /* 構造補齊後的加密內容 */
  51.         memset(src, 0, len);   
  52.         memcpy(src, data, data_len);   
  53.         memset(src + data_len, ch, 8 - data_rest);   
  54.         /* 金鑰置換 */
  55.         memset(block_key, 0, sizeof(block_key));   
  56.         memcpy(block_key, key + 0, 8);   
  57.         DES_set_key_unchecked((const_DES_cblock*)block_key, &ks);   
  58.         memcpy(block_key, key + 8, 8);   
  59.         DES_set_key_unchecked((const_DES_cblock*)block_key, &ks2);   
  60.         memcpy(block_key, key + 16, 8);   
  61.         DES_set_key_unchecked((const_DES_cblock*)block_key, &ks3);   
  62.         printf("before encrypt:\n");   
  63.         for (i = 0; i < len; i++)   
  64.         {   
  65.             printf("0x%.2X ", *(src + i));   
  66.         }   
  67.         printf("\n");   
  68.         /* 迴圈加密/解密,每8位元組一次 */
  69.         count = len / 8;   
  70.         for (i = 0; i < count; i++)   
  71.         {   
  72.             memset(tmp, 0, 8);   
  73.             memset(in, 0, 8);   
  74.             memset(out, 0, 8);   
  75.             memcpy(tmp, src + 8 * i, 8);   
  76.             /* 加密 */
  77.             DES_ecb3_encrypt((const_DES_cblock*)tmp, (DES_cblock*)in, &ks, &ks2, &ks3, DES_ENCRYPT);   
  78.             /* 解密 */
  79.             DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_DECRYPT);  
  80.             /* 將解密的內容拷貝到解密後的明文 */
  81.             memcpy(dst + 8 * i, out, 8);   
  82.         }   
  83.         printf("after decrypt :\n");   
  84.         for (i = 0; i < len; i++)   
  85.         {   
  86.             printf("0x%.2X ", *(dst + i));   
  87.         }   
  88.         printf("\n");   
  89.     }   
  90.     if (NULL != src)   
  91.     {   
  92.         free(src);  
  93.         src = NULL;   
  94.     }   
  95.     if (NULL != dst)   
  96.     {   
  97.         free(dst);   
  98.         dst = NULL;   
  99.     }   
  100.     return 0;   
  101. }  

我給整理了一下,方便閱讀

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/des.h>/************************************************************************ ** 本例採用: **    3des-ecb加密方式; **    24位金鑰,不足24位的右補0x00; **    加密內容8位補齊,補齊方式為:少1位補一個0x01,少2位補兩個0x02,... **        本身已8位對齊的,後面補八個0x08。 ************************************************************************/int main(void){    int docontinue = 1;    unsigned char *data = "hello world!"; /* 明文 */    int data_len;    int data_rest;    unsigned char ch;    unsigned char *src = NULL; /* 補齊後的明文 */    unsigned char *dst = NULL; /* 解密後的明文 */    int len;     unsigned char tmp[8];    unsigned char in[8];    unsigned char out[8];    char *k = "01234567899876543210"; /* 原始金鑰 */    int key_len;#define LEN_OF_KEY              24    unsigned char key[LEN_OF_KEY]; /* 補齊後的金鑰 */    unsigned char block_key[9];    DES_key_schedule ks,ks2,ks3;    /* 構造補齊後的金鑰 */    key_len = strlen(k);    memcpy(key, k, key_len);    memset(key + key_len, 0x00, LEN_OF_KEY - key_len);    /* 分析補齊明文所需空間及補齊填充資料 */    data_len = strlen(data);    data_rest = data_len % 8;    len = data_len + (8 - data_rest);    ch = 8 - data_rest;    src = malloc(len);    dst = malloc(len);    if (NULL == src || NULL == dst)    {        docontinue = 0;    }    if (docontinue)    {        int count;        int i;        /* 構造補齊後的加密內容 */        memset(src, 0, len);        memcpy(src, data, data_len);        memset(src + data_len, ch, 8 - data_rest);        /* 金鑰置換 */        memset(block_key, 0, sizeof(block_key));        memcpy(block_key, key + 0, 8);        DES_set_key_unchecked((const_DES_cblock*)block_key, &ks);        memcpy(block_key, key + 8, 8);        DES_set_key_unchecked((const_DES_cblock*)block_key, &ks2);        memcpy(block_key, key + 16, 8);        DES_set_key_unchecked((const_DES_cblock*)block_key, &ks3);        printf("before encrypt:");        for (i = 0; i < len; i++)        {            printf("0x%.2X ", *(src + i));        }        printf("/n");        /* 迴圈加密/解密,每8位元組一次 */        count = len / 8;        for (i = 0; i < count; i++)        {            memset(tmp, 0, 8);            memset(in, 0, 8);            memset(out, 0, 8);            memcpy(tmp, src + 8 * i, 8);            /* 加密 */            DES_ecb3_encrypt((const_DES_cblock*)tmp, (DES_cblock*)in, &ks, &ks2, &ks3, DES_ENCRYPT);            /* 解密 */            DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_DECRYPT);            /* 將解密的內容拷貝到解密後的明文 */            memcpy(dst + 8 * i, out, 8);        }        printf("after decrypt :");        for (i = 0; i < len; i++)        {            printf("0x%.2X ", *(dst + i));        }        printf("/n");    }    if (NULL != src)    {        free(src);        src = NULL;    }    if (NULL != dst)    {        free(dst);        dst = NULL;    }    return 0;}