3DES 算法

wjf8882300 2010-10-07 02:54:16
在网上找到这么个算法进行3DES加密的,我测试后,发现可以用16密钥对8字节明文加密,对16字节明文加密就失败了。对8字节明文是直接加密的,不知道对16字节明文应该采用什么方法?我目前采用的是以下方法,但是没有成功。
3DES加密的步骤(在以下说到的加密均指DES加密,解密均指DES解密,在3DES加密过程中的DES加密使用左8字节密钥,DES解密使用右8字节密钥):
1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补足8的整数倍)
2)第一组数据D1与初始化向量I异或后的结果依次进行加密解密加密得到第一组密文C1
3)第二组数据D2与第一组的加密结果C1异或以后的结果进行加密解密加密,得到第二组密文C2
4)之后的数据以此类推,得到Cn
5)按顺序连为C1C2C3......Cn即为加密结果。


下面数据供测试,如果哪位高手采用的算法,得出下面的数据,应该就是成功了。
* 16字节密钥,16字节明文
* Key : 0123 4567 89ab cdef fedc ba98 7654 3210
* Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff
* Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
*



int des_set_key( des_context *ctx, uint8 key[8] );
int des3_set_2keys( des3_context *ctx, uint8 key1[8], uint8 key2[8] );
int des3_set_3keys( des3_context *ctx, uint8 key1[8], uint8 key2[8], uint8 key3[8] );

void des_encrypt( des_context *ctx, uint8 input[8], uint8 output[8] );
void des_decrypt( des_context *ctx, uint8 input[8], uint8 output[8] );


void des3_encrypt( des3_context *ctx, uint8 input[8], uint8 output[8] );
void des3_decrypt( des3_context *ctx, uint8 input[8], uint8 output[8] );
...全文
792 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
newfinder 2010-10-13
  • 打赏
  • 举报
回复
3DES加密应该对文件没任何要求,因为在计算机中都是二进制表示,那处理一个txt文件,怎么转换啊?不用转换吗?因为算法里描述都是二进制处理的,所以感觉有点迷惑
wjf8882300 2010-10-13
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 wjf8882300 的回复:]
引用 5 楼 justkk 的回复:
你的代码里面为什么要len/2

uint8 *Input = new uint8[len/2];
Input存放的是比特,前面按照字符串两位一个比特进行存放。这样这个比特数组相当于字符串的1/2长度,后面出现的len/2就是比特数组Input的实际大小。
[/Quote]

不好一起,确切的说应该是字节数组,不是比特数组。
wjf8882300 2010-10-13
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 justkk 的回复:]
你的代码里面为什么要len/2
[/Quote]
uint8 *Input = new uint8[len/2];
Input存放的是比特,前面按照字符串两位一个比特进行存放。这样这个比特数组相当于字符串的1/2长度,后面出现的len/2就是比特数组Input的实际大小。
wjf8882300 2010-10-13
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 newfinder 的回复:]
3DES加密应该对文件没任何要求,因为在计算机中都是二进制表示,那处理一个txt文件,怎么转换啊?不用转换吗?因为算法里描述都是二进制处理的,所以感觉有点迷惑
[/Quote]

要转的,你先把文本数据转换成16进制ASCII码,然后再处理。
wjf8882300 2010-10-13
  • 打赏
  • 举报
回复
1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补足8的整数倍)
2)第一组数据D1与初始化向量I异或后的结果依次进行加密解密加密得到第一组密文C1
3)第二组数据D2与第一组的加密结果C1异或以后的结果进行加密解密加密,得到第二组密文C2
4)之后的数据以此类推,得到Cn
5)按顺序连为C1C2C3......Cn即为加密结果。

按照这个算法描述,加密之后的结果取前8字节的话,那么8字节的明文和16字节的明文,如果前8字节一样,那么密文不就也一样了吗?
justkk 2010-10-12
  • 打赏
  • 举报
回复
你的代码里面为什么要len/2
wjf8882300 2010-10-12
  • 打赏
  • 举报
回复
八字节可以的。
Keys: 0123456789abcdeffedcba9876543210
Inputs: 0123456789abcde7
Outputs: 7f1d0a77826b8aff
Encrypt Inputs: 7f1d0a77826b8aff
Decrypt Outputs: 0123456789abcde7

关键8字节的是直接采用它的函数一步到位。而高于8字节的一般要分组,我不知道我的分组是不是正确的?还有这个算法是不是支持我这样的做法我也不清楚。各位精通加密算法的帮我看看。谢谢。很急。
justkk 2010-10-12
  • 打赏
  • 举报
回复
你先加密完整的8个字节看看
12345678
wjf8882300 2010-10-12
  • 打赏
  • 举报
回复
按照上面3DES算法的描述,我的算法如下:

void Encrypt(const char* keys,const char*inputs,uint8 *Output)
{
//准备密钥
uint8 Key[16];
memset(Key,0,sizeof(Key));
CovertToBytes(Key,sizeof(Key)/sizeof(uint8),keys);

//准备数据
int len = strlen(inputs);
//不是八的倍数
if(len % 8!=0)
{
//补充后长度
len=((len-len%8)/8+1)*8;
}
uint8 *Input = new uint8[len/2];
memset(Input,0,sizeof(Input));
CovertToBytes(Input,len/2,inputs);

//加密
des3_context ctx;
des3_set_2keys(&ctx, Key, Key+8);
//按照上面描述的,应该再这里8字节一组进行加密,不知道我这么写对不对?
for(int i=0;i<len/2;i+=8)
{
uint8 temp[8];
uint8 otemp[8];
//每次取8字节
memcpy(otemp,&Input[i],sizeof(otemp));
des3_encrypt(&ctx, otemp, temp);
memcpy(&Output[i],temp,sizeof(temp));
}

delete Input;
}

为什么我下面的加密结果不正确?
我加密的结果:
Keys: 0123456789abcdeffedcba9876543210
Inputs: 0123456789abcdef0123456789abcdff
Outputs: 27a08440406adf60278f47cf42d615d7
Encrypt Inputs: 1a4d672dca6cb3354a5b052b187c0889
Decrypt Outputs: 14d095af69f566b9c4cf4c7de5f551a4
mymtom 2010-10-07
  • 打赏
  • 举报
回复
对16字节明文, 需要分块处理,最简单的分块方法就是ECB, 每一块分别加密,然后拼接在一起即可。
其他的还有好几种处理方法。
http://www.itl.nist.gov/fipspubs/fip81.htm

69,664

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧