700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > openssl 3des 加解密

openssl 3des 加解密

时间:2021-12-25 19:49:30

相关推荐

openssl 3des 加解密

一. 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)))

二、加密模式

(1)ECB模式

DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

(2)CBC模式

DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:

加密步骤如下:

1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)

2)第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)

3)第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2

4)之后的数据以此类推,得到Cn

5)按顺序连为C1C2C3......Cn即为加密结果。

解密是加密的逆过程,步骤如下:

1)首先将数据按照8个字节一组进行分组得到C1C2C3......Cn

2)将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)

3)将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2

4)之后依此类推,得到Dn

5)按顺序连为D1D2D3......Dn即为解密结果。

这里注意一点,解密的结果并不一定是我们原来的加密数据,可能还含有你补得位,一定要把补位去掉才是你的原来的数据。

三. 3DES API

1. 基本数据结构

typedefunsignedcharDES_cblock[8];typedef/* const */unsignedcharconst_DES_cblock[8];typedefstructDES_ks{union{DES_cblock cblock;DES_LONG deslong[2];} ks[16];} DES_key_schedule;2. 基本宏定义#define DES_ENCRYPT 1#define DES_DECRYPT 0

3. 设置密钥的函数

//根据字符串生成keyvoidDES_string_to_key(constchar*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

intDES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule);//设置密码表,不需要校验voidDES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule);

4. 3DES ECB模式加解密API

voidDES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output,DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3,intenc);参数说明:input:输入数据, 8字节output:输出数据, 8字节ks1:密钥1ks2:密钥2ks3:密钥3enc:加密-DES_ENCRYPT, 解密-DES_DECRYPT5. 3DES CBC模式加解密API

voidDES_ede3_cbc_encrypt(constunsignedchar*input,unsignedchar*output,longlength,DES_key_schedule *ks1, DES_key_schedule *ks2, DES_key_schedule *ks3, DES_cblock *ivec,intenc);参数说明:input: 输入参数, 8字节倍数output: 输出参数, 8字节倍数length: input的长度, 通常为8字节倍数ks1: 密钥1ks2: 密钥2ks3: 密钥3ivec: 初始向量, 8字节, 默认为全0enc: 加密-DES_ENCRYPT, 解密-DES_DECRYPT

四. 3DES 示例

#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;

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 = (unsigned char *)malloc(len);

dst = (unsigned char *)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:\n");

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 :\n");

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;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。