DES —— 数据加密标准

Wesley13
• 阅读 528

DES —— 数据加密标准

DES —— JAVA代码

二话不说,先把代码实现再学习原理!

普通DES代码如下

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @author : R&M www.rmworking.com/blog
 *         2019/8/18 14:40
 *         jsoup_demo
 *         org.security.utils
 */
public class DESUtil {
    public static void main(String[] args) throws Exception {
        // 需要加密的数据
        String str = "qnloft.com(青柠Loft)";
        // 初始化密匙
        byte[] key = DESUtil.initKey();
        System.out.println("密匙:" + Base64.getEncoder().encodeToString(key));
        // 加密
        byte[] encryptData = DESUtil.encrypt(str.getBytes(), key);
        System.out.println("加密结果:" + Base64.getEncoder().encodeToString(encryptData));
        // 解密
        String resutl = new String(DESUtil.decrypt(encryptData, key));
        System.out.println("解密结果:" + resutl);
    }

    private static final String KEY_ALGORITHM = "DES";
    /**
     * 加解密算法/工作模式/填充方式
     */
    private static final String CIPHER_ALGORITHM_PKCS5 = "DES/ECB/PKCS5Padding";

    /**
     * 生成密匙
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] initKey() throws NoSuchAlgorithmException {
        // 实例化密匙生成器
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
        // 初始化密匙生成器
        kg.init(56);
        // 生成密匙
        SecretKey secretKey = kg.generateKey();
        // 二进制形式返回密匙
        return secretKey.getEncoded();
    }

    /**
     * 加密
     * @param data
     * @param key
     * @return
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 还原密匙
        Key k = toKey(key);
        // 实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5);
        // 初始化,设置为解密模式
        cipher.init(Cipher.ENCRYPT_MODE, k);
        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 解密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 还原密匙
        Key k = toKey(key);
        // 实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5);
        // 初始化,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, k);
        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 转换密匙
     * @param key
     * @return
     * @throws InvalidKeyException
     */
    private static Key toKey(byte[] key) throws Exception {
        // 实例化DES密匙材料
        DESKeySpec desKeySpec = new DESKeySpec(key);
        // 实例化密匙工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
        // 生成密匙
        return keyFactory.generateSecret(desKeySpec);
    }

}

三重DES代码如下

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

/**
 * @author : R&M www.rmworking.com/blog
 *         2019/8/25 17:28
 *         jsoup_demo
 *         org.security.utils
 */
public class DESEdeUtil {
    public static void main(String[] args) throws Exception {
        // 需要加密的数据
        String str = "qnloft.com(青柠Loft)";
        // 初始化密匙
        byte[] key = DESEdeUtil.initKey();
        System.out.println("密匙:" + Base64.getEncoder().encodeToString(key));
        // 加密
        byte[] encryptData = DESEdeUtil.encrypt(str.getBytes(), key);
        System.out.println("加密结果:" + Base64.getEncoder().encodeToString(encryptData));
        // 解密
        String resutl = new String(DESEdeUtil.decrypt(encryptData, key));
        System.out.println("解密结果:" + resutl);
    }

    private static final String KEY_ALGORITHM = "DESede";
    /**
     * 加解密算法/工作模式/填充方式
     *
     * 数据补位一般有NoPadding和PKCS7Padding(JAVA中是PKCS5Padding)填充方式
     */
    private static final String CIPHER_ALGORITHM_PKCS5 = "DESede/ECB/PKCS5Padding";

    /**
     * 生成密匙
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static byte[] initKey() throws NoSuchAlgorithmException {
        // 实例化密匙生成器
        KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
        // 初始化密匙生成器
        kg.init(168);
        // 生成密匙
        SecretKey secretKey = kg.generateKey();
        // 二进制形式返回密匙
        return secretKey.getEncoded();
    }

    /**
     * 加密
     * @param data
     * @param key
     * @return
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        // 还原密匙
        Key k = toKey(key);
        // 实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5);
        // 初始化,设置为解密模式
        cipher.init(Cipher.ENCRYPT_MODE, k);
        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 解密
     * @param data
     * @param key
     * @return
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        // 还原密匙
        Key k = toKey(key);
        // 实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_PKCS5);
        // 初始化,设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, k);
        // 执行操作
        return cipher.doFinal(data);
    }

    /**
     * 转换密匙
     * @param key
     * @return
     * @throws InvalidKeyException
     */
    private static Key toKey(byte[] key) throws Exception {
        // 实例化DES密匙材料
        DESedeKeySpec desKeySpec = new DESedeKeySpec(key);
        // 实例化密匙工厂
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(KEY_ALGORITHM);
        // 生成密匙
        return keyFactory.generateSecret(desKeySpec);
    }
}

DES填充方式说明:

  • NoPadding 填充方式:算法本身不填充,
  • PKCS5Padding 填充方式:为JAVA的默认填充方式,对加密数据字节长度对8取余为r,如r大于0,则补8-r个字节,字节为8-r的值;如果r等于0,则补8个字节8。比如:加密字符串为为AAA,则补位为AAA55555;加密字符串为BBBBBB,则补位为BBBBBB22;加密字符串为CCCCCCCC,则补位为CCCCCCCC88888888。

DES —— 消息传递过程

DES —— 数据加密标准

  • 甲方(发送者)生成密钥Key
  • 将生成的key传给乙方
  • 甲方使用密钥对字符串进行加密
  • 甲方加加密后的字符串传给乙方
  • 乙方根据密钥key对字符串进行解密操作

DES和DESEde —— 简介

DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。需要注意的是,在某些文献中,作为算法的DES称为数据加密算法(Data Encryption Algorithm,DEA),已与作为标准的DES区分开来。

1988年后,实例化DES算法破译机的出现,彻底宣告DES算法已经不具备安全性。

3DES(即Triple DES)是DES向AES过渡的加密算法,它使用3条56位的密钥对数据进行三次加密。是DES的一个更安全的变形。它以DES为基本模块,通过组合分组方法设计出分组加密算法。比起最初的DES,3DES更为安全。

DESEde使用两个密钥,执行三次DES算法,加密的过程是加密-解密-加密,解密的过程是解密-加密-解密

  • 3DES加密过程为:C=Ek3(Dk2(Ek1(P)))
  • 3DES解密过程为:P=Dk1(EK2(Dk3(C)))

采用两个密钥进行三重加密的好处有:

  1. 两个密钥合起来有效密钥长度有112bit,可以满足商业应用的需要,若采用总长为168bit的三个密钥,会产生不必要的开销。
  2. 加密时采用加密-解密-加密,而不是加密-加密-加密的形式,这样有效的实现了与现有DES系统的向后兼容问题。因为当K1=K2时,三重DES的效果就和原来的DES一样,有助于逐渐推广三重DES。
  3. 三重DES具有足够的安全性,目前还没有关于攻破3DES的报道。

密匙比较:

DES密匙:   be+SuW5Jnc0=
DESEde密匙:JrkV4N/TXRlkZHP3Aj1h38TCitlRvz1R

从密匙长度我们可以看出三重DES的缺点就是解密的速度会比DES慢很多,时间换安全也是非常值得的事情。

DES —— 算法实现

DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1),其算法主要分为两步:

1.) 初始置换
DES —— 数据加密标准
其功能是把输入的64位数据块按位重新组合,并把输出分为L0、R0两部分,每部分各长32位,其置换规则为将输入的第58位换到第一位,第50位换到第2位……依此类推,最后一位是原来的第7位。L0、R0则是换位输出后的两部分,L0是输出的左32位,R0是右32位,例:设置换前的输入值为D1D2D3……D64,则经过初始置换后的结果为:L0=D58D50……D8;R0=D57D49……D7。

其置换规则见下表:
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7,

2.) 逆置换
DES —— 数据加密标准
经过16次迭代运算后,得到L16、R16,将此作为输入,进行逆置换,逆置换正好是初始置换的逆运算,由此即得到密文输出

--Posted from Rpc

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Linux下DES安全通信编程
des.h///文件名:des.h/功能: 实现DES加密算法的加密解密功能    for linux/
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这