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