3DES加密算法原理

3DES加密算法原理

 

一、3DES加密算法简析:

3DES,也称为 3DESede 或 TripleDES,是三重数据加密算法,相当于是对每个数据库应用三次DES的对称加密算法。

由于DES密码长度容易被暴力破解,所以3DES算法通过对DES算法进行改进,增加DES的密钥长度来避免类似的攻击,针对每个数据块进行三次DES加密;因此,3DES加密算法并非什么新的加密算法,是DES的一个更安全的变形,它以DES为基本模块,通过组合分组方法设计出分组加密算法。。

3DES是DES向AES过渡的加密算法,它使用2个或者3个56位的密钥对数据进行三次加密。相比DES,3DES因密钥长度变长,安全性有所提高,但其处理速度不高。因此又出现了AES加密算法,AES较于3DES速度更快、安全性更高。

 

二、3DES加密过程:

该算法的加解密过程分别是对明文/密文数据进行三次DES加密或解密,得到相应的密文或明文。

假设EK()和DK()分别表示DES的加密和解密函数,P表示明文,C表示密文,那么加解密的公式如下:

加密:C = EK3( DK2( EK1(P)) ),即对明文数据进行,加密 –> 解密 –> 加密的过程,最后得到密文数据;

解密:P = DK1( EK2( DK3(C)) ),即对密文数据进行,解密 –> 加密 –> 解密的过程,最后得到明文数据;

其中:K1表示3DES中第一个8字节密钥,K2表示第二个8字节密钥,K3表示第三个8字节密钥,K1、K2、K3决定了算法的安全性,若三个密钥互不相同,本质上就相当于用一个长为168位的密钥进行加密。多年来,它在对付强力攻击时是比较安全的。若数据对安全性要求不那么高,K1可以等于K3。在这种情况下,密钥的有效长度为112位,即K1对应KL(左8字节),K2对应KR(右8字节),K3对应KL(左8字节)。

3DES加密算法原理

当三重密钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可实现对普通DES加密算法的兼容。

3DES加密算法原理

由于DES加解密算法是每8个字节作为一个加解密数据块,因此在实现该算法时,需要对数据进行分块和补位(即最后不足8字节时,要补足8字节)。Java本身提供的API中NoPadding,Zeros填充和PKCS5Padding。假设我们要对9个字节长度的数据进行加密,则其对应的填充说明如下:

(1)NoPadding:API或算法本身不对数据进行处理,加密数据由加密双方约定填补算法。例如若对字符串数据进行加解密,可以补充\0或者空格,然后trim;

(2)ZerosPadding:无数据的字节全部被填充为0;

第一块:F0 F1 F2 F3 F4 F5 F6 F7

第二块:F8 0 0 0 0 0 0 0

(3)PKCS5Padding:每个被填充的字节都记录了被填充的长度;

①加密前:数据字节长度对8取余,余数为m,若m>0,则补足8-m个字节,字节数值为8-m,即差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8。

②解密后:取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文。

③加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。

(4)PKCS7Padding:

PKCS7Padding 的填充方式和PKCS5Padding 填充方式一样。只是加密块的字节数不同。PKCS5Padding明确定义了加密块是8字节,PKCS7Padding加密快可以是1-255之间。

 

三、3DES解密:

3DES解密过程,与加密过程相反,即逆序使用密钥。是以密钥3、密钥2、密钥1的顺序执行 解密->加密->解密

3DES加密算法原理

 

 

四、Java使用3DES加密解密的流程:

3des加密解密详细解释

  ①传入共同约定的密钥(keyBytes)以及算法(Algorithm),来构建SecretKey密钥对象:

  SecretKey deskey = new SecretKeySpec(keyBytes, Algorithm);

  ②根据算法实例化Cipher对象,它负责加密/解密:

  Cipher c1 = Cipher.getInstance(Algorithm);

  ③传入加密/解密模式以及SecretKey密钥对象,实例化Cipher对象:

  c1.init(Cipher.ENCRYPT_MODE, deskey);

  ④传入字节数组,调用Cipher.doFinal()方法,实现加密/解密,并返回一个byte字节数组:

  c1.doFinal(src);

Java语言加密案例:

/*字符串 DESede(3DES) 加密*/
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
 
public class Des3 {
 
    private static final String Algorithm = "DESede"; // 定义 加密算法,可用DES,DESede,Blowfish

    // 加密函数
    // keybyte为加密密钥,长度为24字节
    // src为被加密的数据缓冲区(源)
    public static byte[] encryptMode(byte[] keybyte, byte[] src) {
        try {
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            // 加密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }
 
    // 解密函数
    // keybyte为加密密钥,长度为24字节
    // src为加密后的缓冲区
    public static byte[] decryptMode(byte[] keybyte, byte[] src) {
        try {
            // 生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            // 解密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }
 
    // 转换成十六进制字符串
    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
            if (n < b.length - 1) {
                hs = hs + ":";
            }
        }
        return hs.toUpperCase();
    }
 
    public static void main(String[] args) {
 
        // 添加新安全算法,如果用JCE就要把它添加进去
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
        final byte[] keyBytes = { 0x11, 0x22, 0x4F, 0x58, (byte) 0x88, 0x10, 0x40, 0x38, 0x28, 0x25, 0x79, 0x51, (byte) 0xCB, (byte) 0xDD, 0x55, 0x66, 0x77, 0x29, 0x74, (byte) 0x98, 0x30, 0x40, 0x36, (byte) 0xE2 }; // 24字节的密钥
 
        String szSrc = "This is a 3DES test. 测试";
        System.out.println("加密前的字符串:" + szSrc);
 
        byte[] encoded = encryptMode(keyBytes, szSrc.getBytes());
        System.out.println("加密后的字符串:" + new String(encoded));
 
        byte[] srcBytes = decryptMode(keyBytes, encoded);
        System.out.println("解密后的字符串:" + (new String(srcBytes)));
    }
}

 

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/100048.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 转载:ipmi主要的应用

    转载:ipmi主要的应用

  • DropDownList绑定数据源的方法[通俗易懂]

    DropDownList绑定数据源的方法[通俗易懂]web       DropDownList绑定数据源的几种方式 第一种                this.ddltype.DataTextField= “btName”;//显示的值                this.ddltype.DataValueField=”btId”;//获取dropdownlist中的值                ddltype.

  • GC overhead limit exceeded 问题分析与解决

    GC overhead limit exceeded 问题分析与解决今天出现了一个很奇怪的异常:java.lang.OutOfMemoryError:GCoverheadlimitexceeded,超出了GC开销限制。科普了一下,这个是JDK6新添的错误类型。是发生在GC占用大量时间为释放很小空间的时候发生的,是一种保护机制。一般是因为堆太小,导致异常的原因:没有足够的内存。Sun官方对此的定义:超过98%的时间用来做GC并且回收了不到2%…

  • 学习算法 – 优先级队列二叉堆实现

    学习算法 – 优先级队列二叉堆实现

  • compound extremes_one是什么

    compound extremes_one是什么前言eXtremeComponents是一系列提供高级显示的开源JSP定制标签。当前的包含的组件为eXtremeTable,用于以表的形式显示数据。本文档处于更新中。大部分章节我将仅仅描述如何使用eXtremeTable。当然,为了使程序高效并具有更高的灵活性,源代码被再三重构。随后,我认为阐述一下如何做设计决定是值得的。我希望大家能知道使用extremeTable是多么容易,并且

  • mysql优化器不能使用hash索引来加速_数据库主键索引和唯一索引的区别

    mysql优化器不能使用hash索引来加速_数据库主键索引和唯一索引的区别1.hash表只能匹配是否相等,不能实现范围查找select * from xx where id > 23; 这时就没办法索引了2.当需要按照索引进行order by时,hash值没办法支持排序select * from xx order by score desc;如果score为建立索引的字段,hash值没办法辅助排序。3.组合索引可以支持部分索引查询,如(a,b,c)的组合索引,查询中只用到了阿和b也可以查询的,如果使用hash表,组合索引会将几个字段合并hash,没办法支持部分索引

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号