利用openssl库测试3DES ECB模式算法的实现

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/des.h>

#define LEN_OF_KEY 24

/************************************************************************
** 3des-ecb加密方式; 
** 24位密钥,不足24位的右补0x00;
** 加密内容8字节补齐
** 返回值:密文长度
************************************************************************/
int do_3DES_ECB_Encrypt(unsigned char *keyData, int klen, unsigned char *srcData, unsigned int slen, unsigned char *dstData, unsigned int dlen)
{
    int count = 0;
    int i = 0;
    unsigned char in[8] = {0};
    unsigned char out[8] = {0};
    unsigned char key[LEN_OF_KEY] = {0}; /* 密钥buffer */
    unsigned char block_key[9];
    DES_key_schedule ks,ks2,ks3;           /* 构造补齐后的密钥 */

    if((dlen < slen) || (dlen < 8) || (klen > 24)) return -1;
    if(dlen != slen)
    {
        if((dlen - slen) < (8-slen%8)) return -1;
    }    
    else
    {
        if(dlen % 8) return -1;
    }
    
    memcpy(key, keyData, klen);
    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);
    
    /*循环加密,每8字节一次*/
    count =slen/8;
    for(i=0; i<count; i++)
    {
        memset(in, 0, 8);
        memset(out, 0, 8);
        memcpy(in, srcData+8*i,8);
        /*加密*/
        DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_ENCRYPT); 
        memcpy(dstData + 8*i, out, 8); /*将加密的内容拷贝到缓存区*/
    }
    
    if(slen%8)
    {
        memset(in, 0, 8);
        memset(out, 0, 8);
        memcpy(in, srcData+8*i,slen%8);
        /*加密*/
        DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_ENCRYPT); 
        memcpy(dstData + 8*i, out, 8);/*将加密的内容拷贝到缓存区*/
    }
    
    return (slen%8?(++i*8):slen);
    
}


/************************************************************************
** 3des-ecb解密方式; 
** 24位密钥,不足24位的右补0x00;
** 返回值:明文长度
************************************************************************/
int do_3DES_ECB_Decrypt(unsigned char *keyData, int klen, unsigned char *srcData, unsigned int slen, unsigned char *dstData, unsigned int dlen)
{
    int count = 0;
    int i = 0;
    unsigned char in[8] = {0};
    unsigned char out[8] = {0};
    unsigned char key[LEN_OF_KEY] = {0}; /* 密钥buffer */
    unsigned char block_key[9] = {0};
    DES_key_schedule ks,ks2,ks3;           /* 构造补齐后的密钥 */
    
    if((slen%8) || (dlen < slen) || (klen > LEN_OF_KEY)) return -1;

    memcpy(key, keyData, klen);
    
    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);
    
    /*循环解,每8字节一次*/
    count =slen/8;
    for(i=0; i<count; i++)
    {
        memset(in, 0, 8);
        memset(out, 0, 8);
        memcpy(in, srcData+8*i,8);
        /*加密*/
        DES_ecb3_encrypt((const_DES_cblock*)in, (DES_cblock*)out, &ks, &ks2, &ks3, DES_DECRYPT); 
        memcpy(dstData + 8*i, out, 8); /*将加密的内容拷贝到缓存区*/
    }
    
    return slen;
}

/************************************************************************
**test 3DES ECB modle

gcc openssl_3des.c -g -o test_3dec_ecb -lcrypto -lssl

************************************************************************/
int main(void)
{
    char testbuf[] = "hello world! hello world! hello world!";/*?明文?*/
    char key[] = "01234567899876543210"; /* 原始密钥 */
    char enc_buf[100]= {0};
    char dec_buf[100]= {0};
    int len = 0;
    int i = 0;
    
    printf("encrypt len=%d:\r\n", (int)sizeof(testbuf));
    len = do_3DES_ECB_Encrypt(key, sizeof(key), testbuf, sizeof(testbuf), enc_buf, 100);
    
    printf("mw len=%d:\r\n", len);
    for(i=0; i<len; i++)
    {
        printf("0x%x ", enc_buf[i]);
        if((i>0) && (i%16 == 0)) printf("\r\n");
    }
    printf("\r\n");
    
    
    printf("decrypt len = %d:\r\n", len);
    len = do_3DES_ECB_Decrypt(key, sizeof(key), enc_buf, len, dec_buf, 100);
    
    for(i=0; i<len; i++)
    {
        printf("%c", dec_buf[i]);
    }
    printf("\r\n");
    return 0;

猜你喜欢

转载自blog.csdn.net/zhangkun2609/article/details/84947074