利用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;
}