HardBirch

3DES算法Java与C的兼容问题详细分析与实现

时间:12-11-01 栏目:系统技术篇 作者:魔豆先生 评论:4 点击: 14,630 次

一、引言

3DES算法JavaC兼容问题详细分析与实现,目前移动互联网领域android端的开发与Iphone端的开发才用的是java与object-c两种语言,面对编码算法的实现上Java有自带的库可以使用,C可能不具备相关配套的库,或者java与java是互通的,java与C的互通存在着“问题”,怎么办呢?很多的程序员只是知其然不知其所以然,这个不是好习惯~,程序员需要苦练内功。

(1)多看Linux内核源码;这个是相当优秀的一本宝典,相当有助于加深内功。

(2)多看内部lib的实现,多看算法的spec和源码;这个是解决棘手问题的关键,平时未必显现的出来。

 

二、问题来源

废话少说,直插主题!

先从疑问开始,看过C语言版本3DES算法和Java版的童鞋,肯定会产生这样的几个疑问(如果没有疑问,那么恭喜您,已经不需要看此文了):

(1)C的实现需要3个key来进行3次DES的编/解码操作,但是Java的实现传入参数只有一个;

(2)在编码的spec中有描述过MODE,常见MODE包括有ECB/CBC/CFB/OFB四种,他们分别使用了哪一种?是否是一致的?

(3)在编码的spec中有描述过PADDING,常用的PKCS#7和PKCS#5,那么他们分别使用的是什么方式呢,是否一致的?

 

三、背景知识解释

首先、解释上段落第2点钟提到的MODE。MODE指的是加密模式。加密算法是按块进行加密的,DES是64bit(8 bytes)一个块进行加密,每次输入8个字节的明文,输出8个字节密文,如果是明文一共16个字节长,则分成两组依次进行加密。

(1) 例如明文是 1234567812345678,那么加密的结果类似C21431262C779CC21431262C779C,看出了什么没,是的,重复了两遍,这钟MODE就是ECB。分组之间没有联系,组和组明文相同,那么密文也是相同的,容易被发现规律。

(2)为了解决这个问题,出现了新的加密模式,分组连接模式(CBC),密码反馈模式(CFB),输出反馈模式(OFB)。

CBC 是需要给一个初始化的向量,然后将每个输出与该向量作运算,并将运算的结果作为下一个加密块的初始化向量,CFB 和 OFB 则不需要提供初始化向量,直接将密码或者输出作为初始化向量进行计算;避免了明文的规律性出现反应在密文中。当然带来的问题是,解密的时候必须接收完整才能开始解密。如果其中部分信息网络接收出错,会导致整个解密失败,而ECB仅影响网络传输出错的那个块的解密。

 

其次、解释上段落第3点钟提到的PADDING。padding在这里指填充方式,例如明文是10位,按照8bytes分组,正好1组多2个byte,这2个byte怎么加密?这时候必须对明文进行Padding操作。padding的方式很多,在《跨语言的加解密兼容问题讨论》 一文中有比较想起的对比。

(1)一种PKCS#7,该填充方法是将每一个补充的字节内容填充为填充的字节个数;在这里我们需要填充的6个'0x6';

(2)另一种PKCS#5,和PKCS#7的区别就 是,分组的大小为8个字节。

(3)另外,就是如果明文刚刚好进行分组,那么需要补充一个独立的分组。如 DES明文:12345678,为 8 个字节,则必须补充8个0×08至16个字节,然后进行加密;解密后的字符串为12345678\x08\x08\x08\x08\x08\x08\x08\x08,需要去掉多余的, 0×08的到原文。

 

四、问题的源码分析

在熟悉了相应的编码相关知识之后,来阅读源码分析疑惑:

(1)针对key的问题在Java的源码DESedeEngine.java中有如下两段代码可以说明:

DESedeEngine class中定义了如下三个key数组:

3个key数组分别被初始化长度为8 bytes,而且传入的key字串的长度被检查是否大于24,所以豁然开朗,这就是java应用调用的时候传入所谓一个KEY的真正原因。

 

(2)针对MODE的问题,Java默认的实现才用的是ECB编码的方式,所以C代码开启ECB编码的宏;Java默认编码的BLOCK_SIZE 和C代码的实现是一样的,都是8,所以MODE的问题解决了。如下图所示:

C代码开启ECB编码方式:

Java代码编码块长度为8与C代码实现相同:

(3)针对Padding的问题,由于很容实现,所以C代码上就委屈一点,自动实现Java的PKCS#7方式编码,如下图所示,所以问题也解决了。

五、兼容算法的最终实现

所以从宏观的角度看,C代码最终的实现是形如下图所示。

encrypt()是DES编码函数实现,decrypt是DES解码函数实现,组合成3DES算法的加密实现。

Java的实现很容易,网路上很常见,COPY一份如下所示:

六、HEX2BYTE 与 BYTE2HEX的实现

编码算法为了能让编码之后的数据直接查看,很多时候会有Hex2Byte 与 byte2Hex函数来实现可视化,提供附加函数如下:

#define BETWEEN(VAL, vmin, vmax) ((VAL) >= (vmin) && (VAL) <= (vmax))

/**************************************************
*函数名称 HEX2BYTE
*功能描述 单个十六进制字符转其对应的数值
*返回值    转换后整数值
*************************************************/
uint8 HEX2BYTE(uint8 hex_ch)
{
if (hex_ch >= '0' && hex_ch <= '9')
{
return hex_ch - '0';
}

if (hex_ch >= 'a' && hex_ch <= 'f')
{
return hex_ch - 'a' + 10;
}

if (hex_ch >= 'A' && hex_ch <= 'F')
{
return hex_ch - 'A' + 10;
}

return 0x00;
}

/**************************************************
*函数名称 BYTE2HEX
*功能描述 将0X0-0xF的整数转换为对应的十六进制字符
*返回值    转换后的十六进制字符
*************************************************/
char BYTE2HEX(uint8 int_val)
{
if (BETWEEN(int_val, 0, 9))
{
return int_val + 0x30;
}

if (BETWEEN(int_val, 0xa, 0xf))
{
return (int_val - 0xa) + 'a';
}

return '0';
}

祝愉快!

 

 

 

声明: 本文由( 魔豆先生 )原创编译,转载请保留链接: 3DES算法Java与C的兼容问题详细分析与实现

3DES算法Java与C的兼容问题详细分析与实现:目前有4 条留言

  1. 地板
    cccisbug:

    加密的过程设置了padding值之后,解密的结果多出来的padding怎么去掉呢

    2014-09-04 11:09 [回复]
  2. 板凳
    wewebi:

    请问有没有对应的C与java的源码,请发我邮箱,wewebi@126.com非常感谢。

    2015-06-23 16:57 [回复]
  3. 沙发
    jober:

    最近也在处理真个问题,大神求下C与java的对应源码,麻烦发我邮箱,ijober@126.com非常感谢。

    2016-02-19 18:14 [回复]
    • 叉,思路都分享嘚那么清楚了,总是有这样的人,麻烦发到我的邮箱,麻烦我给我QQ,忽然想到了公众号【迷蒙】,凭什么!

      2016-02-25 17:39 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐