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)
blank

相关推荐

  • msfconsole 控制台使用和操作[通俗易懂]

    msfconsole 控制台使用和操作[通俗易懂]Msfconsole提供了一个一体化的集中控制台。通过msfconsole,你可以访问和使用所有的metasploit的插件,payload,利用模块,post模块等等。Msfconsole还有第三方程序的接口,比如nmap,sqlmap等,可以直接在msfconsole里面使用。在启动MSF终端之后,可以首先输入help命令列出MSF终端所支持的命令列表,包括核心命令集和后端数据库命令集。对于…

  • python强制删除文件夹_python删除文件夹下的文件保留但清空子文件夹

    python强制删除文件夹_python删除文件夹下的文件保留但清空子文件夹importosimportshutil#删除文件夹下的文件&&保留但清空子文件夹defdel_file(filepath):print(“hello”)listdir=os.listdir(filepath)#获取文件和子文件夹print(listdir)fordirnameinlistdir:dirname=filepath+”//”+dir…

  • oracle 用户赋权_oracle数据库创建只读用户

    oracle 用户赋权_oracle数据库创建只读用户ORACLE创建用户赋予权限删除用户oracle数据库的权限系统分为系统权限与对象权限。一.ORACLE默认管理员密码二.创建用户及密码。三.赋予权限。oracle数据库的权限系统分为系统权限与对象权限。系统权限(databasesystemprivilege)可以让用户执行特定的命令集。例如,createtable权限允许用户创建表,grantanyprivilege权限允许用户授予任何系统权限。对象权限(databaseobjectprivilege)可以让用户能

    2022年10月29日
  • git删除远程分支

    1.git删除远程分支gitpushorigin–delete[branch_name]2.删除本地分支区别gitbranch-d会在删除前检查merge状态(其与上游分支或者与head)。gitbranch-D是gitbranch–delete–force的简写,它会直接删除。共同点都是删除本地分支的方法(与删除远程分支命令相独立,要想本地和远程都删除,必须得运行两个命令)。3.git查看分支:查看本地分支gitbranch查看远程分支

  • Corners检测「建议收藏」

    Corners检测「建议收藏」HarrisCorners角点检测使用harriscorners检测器:使用OpenCV函数voidcornerHarris(InputArraysrc,OutputArraydst,intblockSize,                intksize,doublek,

    2022年10月22日
  • vim保存并退出有几种方法_ubuntu vim保存退出命令

    vim保存并退出有几种方法_ubuntu vim保存退出命令vim基础保存退出命令vimxxx.file输入文件内容;ins按键,切换插入和增加按ESC,左下角就可以进行输入:w保存但不退出:wq保存并退出:q退出:q!强制退出,不保存:e!放弃所有修改,从上次保存文件开始再编辑命令历史…

发表回复

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

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