DES 加密 API


DES_ecb3_encrypt()  encrypts/decrypts the  input  block by using three-key Triple-DES encryption in  ECB mode. This involves encrypting the input with  ks1 , decrypting with the key schedule  ks2 , and then encrypting with  ks3 . This routine greatly reduces the chances of brute force breaking of  DES  and has the advantage of if  ks1 ,  ks2  and  ks3  are the same, it is equivalent to just encryption using  ECB  mode and  ks1  as the key.

encrypting the input with   ks1
decrypting with the key schedule   ks2
 encrypting with   ks3


https://linux.die.net/man/3/des_ecb2_encrypt




OpenSSL编程-3DES编程详解

本文由 大佟 发表于 2014年06月10日 , 浏览: 7,235次 , 评论: 0条
一. 3DES加密原理

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,这样:
3DES加密(EDE)过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密(DED)过程为:P=Dk1(EK2(Dk3(C)))

二. 3DES API

1. 基本数据结构

typedef unsigned char DES_cblock[8];
typedef /* const */ unsigned char const_DES_cblock[8];

typedef struct DES_ks
{
union
{
DES_cblock cblock;
DES_LONG deslong[2];
} ks[16];
} DES_key_schedule;

sizeof(DES_cblock) = 8字节
sizeof(const_DES_cblock ) = 8字节
sizeof(DES_key_schedule) = 128字节
2. 基本宏定义

1
2
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
3. 设置密钥函数


//根据字符串生成key
void DES_string_to_key(const char *str, DES_cblock *key);

//设置密码表,并进行校验
//will check that the key passed is of odd parity and is not a week or semi-weak key.
//If the parity is wrong, then -1 is returned. If the key is a weak key, then -2 is returned.
//If an error is returned, the key schedule is not generated
int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);

//设置密码表,不需要校验
void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
4. 3DES ECB模式加解密API


void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, int enc);

参数说明:
input:输入数据, 8字节
output:输出数据, 8字节
ks1:密钥1
ks2:密钥2
ks3:密钥3
enc:加密-DES_ENCRYPT, 解密-DES_DECRYPT
5. 3DES CBC模式加解密API


void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, long length,
DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec, int enc);

参数说明:
input: 输入参数, 8字节倍数
output: 输出参数, 8字节倍数
length: input的长度, 通常为8字节倍数
ks1: 密钥1
ks2: 密钥2
ks3: 密钥3
ivec: 初始向量, 8字节, 默认为全0
enc: 加密-DES_ENCRYPT, 解密-DES_DECRYPT
三. 3DES 示例

1. 3DES ECB模式示例


#include
#include
#include
#include
#include

#include "hex.h"

/************************************************************************
* 3DES-ECB加密方式
* 8字节密钥,加密内容8位补齐,补齐方式为:PKCS7。
*
* file: test_des3_ecb.c
* gcc -Wall -O2 -o test_des3_ecb test_des3_ecb.c hex.c -lcrypto
*
* author: [email protected] by www.qmailer.net
************************************************************************/
int main(int argc, char *argv[])
{
int i = 0;
int len = 0;
int nlen = 0;

char ch = '\0';
char *key1 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key2 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key3 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *data = "12345678123456781234567812345678"; /* 原始明文, 十六进制字符串 */
unsigned char src[64] = {0};
unsigned char out[64] = {0};
unsigned char tmp[64] = {0};

unsigned char *ptr = NULL;
unsigned char block[8] = {0};
DES_key_schedule ks1, ks2, ks3;

/* 设置密码表 */
ptr = hex2bin(key1, strlen(key1), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks1);

ptr = hex2bin(key2, strlen(key2), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks2);

ptr = hex2bin(key3, strlen(key3), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks3);

ptr = hex2bin(data, strlen(data), &nlen);
memcpy(src, ptr, nlen);
free(ptr);

len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;

ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);

printf("加密前数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(src + i));
}
printf("\n");

for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((C_Block *)(src + i), (C_Block *)(out + i), &ks1, &ks2, &ks3, DES_ENCRYPT);
}

printf("加密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X" , *(out + i));
}
printf("\n");

for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((C_Block *)(out + i), (C_Block *)(tmp + i), &ks1, &ks2, &ks3, DES_DECRYPT);
}

printf("解密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(tmp + i));
}
printf("\n");

return 0;
}
2. 3DES CBC模式示例


#include
#include
#include
#include
#include

#include "hex.h"

/************************************************************************
* 3DES-ECB加密方式
* 8字节密钥,加密内容8位补齐,补齐方式为:PKCS7。
*
* file: test_des3_ecb.c
* gcc -Wall -O2 -o test_des3_cbc test_des3_cbc.c hex.c -lcrypto
*
* author: [email protected] by www.qmailer.net
************************************************************************/
int main(int argc, char *argv[])
{
int i = 0;
int len = 0;
int nlen = 0;

char ch = '\0';
char *key1 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key2 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key3 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *data = "12345678123456781234567812345678"; /* 原始明文, 十六进制字符串 */
unsigned char src[64] = {0};
unsigned char out[64] = {0};
unsigned char tmp[64] = {0};

unsigned char *ptr = NULL;
unsigned char block[8] = {0};
DES_key_schedule ks1, ks2, ks3;
DES_cblock ivec;
DES_cblock ivsetup = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

/* 设置密码表 */
ptr = hex2bin(key1, strlen(key1), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks1);

ptr = hex2bin(key2, strlen(key2), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks2);

ptr = hex2bin(key3, strlen(key3), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks3);

ptr = hex2bin(data, strlen(data), &nlen);
memcpy(src, ptr, nlen);
free(ptr);

len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;

ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);

printf("加密前数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(src + i));
}
printf("\n");

memcpy(ivec, ivsetup, sizeof(ivsetup));
/* 按照8字节数据进行加密,length=8 */
for (i = 0; i < len; i += 8) {
DES_ede3_cbc_encrypt(src + i, out + i, 8, &ks1, &ks2, &ks3, &ivec, DES_ENCRYPT);
}

printf("加密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X" , *(out + i));
}
printf("\n");

memcpy(ivec, ivsetup, sizeof(ivsetup));
/* 按照8字节数据进行解密,length=8 */
for (i = 0; i < len; i += 8) {
DES_ede3_cbc_encrypt(out + i, tmp + i, 8, &ks1, &ks2, &ks3, &ivec, DES_DECRYPT);
}

printf("解密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(tmp + i));
}
printf("\n");

return 0;
}
3. 输出结果


# ECB模式
加密前数据: 12345678123456781234567812345678
加密后数据: 4A438AC15D8074B54A438AC15D8074B5
解密后数据: 12345678123456781234567812345678

# CBC模式
加密前数据: 12345678123456781234567812345678
加密后数据: 4A438AC15D8074B58244AE0E7477AF78
解密后数据: 12345678123456781234567812345678
由结果可见,ECB和CBC模式的第一个8字节加密结果一致,而CBC模式的第二个8字节起会不断变化,同时,如果k1=k2=k3,则加密结果和DES加密算法相同。

四. HEX转换函数

请参考前面的Blog:《OpenSSL编程-DES编程详解》

归类:C/OOC编程, 互联网金融, 编程开发 ,标签:3DES, OpenSSL

OpenSSL编程-3DES编程详解

本文由 大佟 发表于 2014年06月10日 , 浏览: 7,235次 , 评论: 0条
一. 3DES加密原理

3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。它相当于是对每个数据块应用三次DES加密算法。由于计算机运算能力的增强,原版DES密码的密钥长度变得容易被暴力破解;3DES即是设计用来提供一种相对简单的方法,即通过增加DES的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。

3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设Ek()和Dk()代表DES算法的加密和解密过程,K代表DES算法使用的密钥,P代表明文,C代表密文,这样:
3DES加密(EDE)过程为:C=Ek3(Dk2(Ek1(P)))
3DES解密(DED)过程为:P=Dk1(EK2(Dk3(C)))

二. 3DES API

1. 基本数据结构

typedef unsigned char DES_cblock[8];
typedef /* const */ unsigned char const_DES_cblock[8];

typedef struct DES_ks
{
union
{
DES_cblock cblock;
DES_LONG deslong[2];
} ks[16];
} DES_key_schedule;

sizeof(DES_cblock) = 8字节
sizeof(const_DES_cblock ) = 8字节
sizeof(DES_key_schedule) = 128字节
2. 基本宏定义

1
2
#define DES_ENCRYPT 1
#define DES_DECRYPT 0
3. 设置密钥函数

//根据字符串生成key
void DES_string_to_key(const char *str, DES_cblock *key);

//设置密码表,并进行校验
//will check that the key passed is of odd parity and is not a week or semi-weak key.
//If the parity is wrong, then -1 is returned. If the key is a weak key, then -2 is returned.
//If an error is returned, the key schedule is not generated
int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);

//设置密码表,不需要校验
void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);
4. 3DES ECB模式加解密API


void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,
DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, int enc);

参数说明:
input:输入数据, 8字节
output:输出数据, 8字节
ks1:密钥1
ks2:密钥2
ks3:密钥3
enc:加密-DES_ENCRYPT, 解密-DES_DECRYPT
5. 3DES CBC模式加解密API


void DES_ede3_cbc_encrypt(const unsigned char *input,unsigned char *output, long length,
DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec, int enc);

参数说明:
input: 输入参数, 8字节倍数
output: 输出参数, 8字节倍数
length: input的长度, 通常为8字节倍数
ks1: 密钥1
ks2: 密钥2
ks3: 密钥3
ivec: 初始向量, 8字节, 默认为全0
enc: 加密-DES_ENCRYPT, 解密-DES_DECRYPT
三. 3DES 示例

1. 3DES ECB模式示例


#include
#include
#include
#include
#include

#include "hex.h"

/************************************************************************
* 3DES-ECB加密方式
* 8字节密钥,加密内容8位补齐,补齐方式为:PKCS7。
*
* file: test_des3_ecb.c
* gcc -Wall -O2 -o test_des3_ecb test_des3_ecb.c hex.c -lcrypto
*
* author: [email protected] by www.qmailer.net
************************************************************************/
int main(int argc, char *argv[])
{
int i = 0;
int len = 0;
int nlen = 0;

char ch = '\0';
char *key1 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key2 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key3 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *data = "12345678123456781234567812345678"; /* 原始明文, 十六进制字符串 */
unsigned char src[64] = {0};
unsigned char out[64] = {0};
unsigned char tmp[64] = {0};

unsigned char *ptr = NULL;
unsigned char block[8] = {0};
DES_key_schedule ks1, ks2, ks3;

/* 设置密码表 */
ptr = hex2bin(key1, strlen(key1), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks1);

ptr = hex2bin(key2, strlen(key2), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks2);

ptr = hex2bin(key3, strlen(key3), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks3);

ptr = hex2bin(data, strlen(data), &nlen);
memcpy(src, ptr, nlen);
free(ptr);

len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;

ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);

printf("加密前数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(src + i));
}
printf("\n");

for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((C_Block *)(src + i), (C_Block *)(out + i), &ks1, &ks2, &ks3, DES_ENCRYPT);
}

printf("加密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X" , *(out + i));
}
printf("\n");

for (i = 0; i < len; i += 8) {
DES_ecb3_encrypt((C_Block *)(out + i), (C_Block *)(tmp + i), &ks1, &ks2, &ks3, DES_DECRYPT);
}

printf("解密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(tmp + i));
}
printf("\n");

return 0;
}
2. 3DES CBC模式示例


#include
#include
#include
#include
#include

#include "hex.h"

/************************************************************************
* 3DES-ECB加密方式
* 8字节密钥,加密内容8位补齐,补齐方式为:PKCS7。
*
* file: test_des3_ecb.c
* gcc -Wall -O2 -o test_des3_cbc test_des3_cbc.c hex.c -lcrypto
*
* author: [email protected] by www.qmailer.net
************************************************************************/
int main(int argc, char *argv[])
{
int i = 0;
int len = 0;
int nlen = 0;

char ch = '\0';
char *key1 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key2 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *key3 = "0000000000000000"; /* 原始密钥, 十六进制字符串 */
char *data = "12345678123456781234567812345678"; /* 原始明文, 十六进制字符串 */
unsigned char src[64] = {0};
unsigned char out[64] = {0};
unsigned char tmp[64] = {0};

unsigned char *ptr = NULL;
unsigned char block[8] = {0};
DES_key_schedule ks1, ks2, ks3;
DES_cblock ivec;
DES_cblock ivsetup = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

/* 设置密码表 */
ptr = hex2bin(key1, strlen(key1), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks1);

ptr = hex2bin(key2, strlen(key2), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks2);

ptr = hex2bin(key3, strlen(key3), &nlen);
memcpy(block, ptr, sizeof(block));
free(ptr);
DES_set_key_unchecked((C_Block *)block, &ks3);

ptr = hex2bin(data, strlen(data), &nlen);
memcpy(src, ptr, nlen);
free(ptr);

len = (nlen / 8 + (nlen % 8 ? 1: 0)) * 8;

ch = 8 - nlen % 8;
memset(src + nlen, ch, (8 - nlen % 8) % 8);

printf("加密前数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(src + i));
}
printf("\n");

memcpy(ivec, ivsetup, sizeof(ivsetup));
/* 按照8字节数据进行加密,length=8 */
for (i = 0; i < len; i += 8) {
DES_ede3_cbc_encrypt(src + i, out + i, 8, &ks1, &ks2, &ks3, &ivec, DES_ENCRYPT);
}

printf("加密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X" , *(out + i));
}
printf("\n");

memcpy(ivec, ivsetup, sizeof(ivsetup));
/* 按照8字节数据进行解密,length=8 */
for (i = 0; i < len; i += 8) {
DES_ede3_cbc_encrypt(out + i, tmp + i, 8, &ks1, &ks2, &ks3, &ivec, DES_DECRYPT);
}

printf("解密后数据: ");
for (i = 0; i < len; i++) {
printf("%02X", *(tmp + i));
}
printf("\n");

return 0;
}
3. 输出结果


# ECB模式
加密前数据: 12345678123456781234567812345678
加密后数据: 4A438AC15D8074B54A438AC15D8074B5
解密后数据: 12345678123456781234567812345678

# CBC模式
加密前数据: 12345678123456781234567812345678
加密后数据: 4A438AC15D8074B58244AE0E7477AF78
解密后数据: 12345678123456781234567812345678
由结果可见,ECB和CBC模式的第一个8字节加密结果一致,而CBC模式的第二个8字节起会不断变化,同时,如果k1=k2=k3,则加密结果和DES加密算法相同。

四. HEX转换函数

请参考前面的Blog:《OpenSSL编程-DES编程详解》

归类:C/OOC编程, 互联网金融, 编程开发 ,标签:3DES, OpenSSLhttp://www.qmailer.net/archives/208.html

OpenSSL编程-3DES编程详解


http://www.qmailer.net/archives/208.html



原创声明:除非注明,本站文章均为原创!转载请注明来自 嗨!大佟! www.qmailer.net
本文链接:http://www.qmailer.net/archives/208.html



你可能感兴趣的:(Linux)