des 向量 java_在JAVA中使用DES算法

DES算法提供CBC, OFB, CFB, ECB四种模式,MAC是基于ECB实现的。

一、数据补位

DES数据加解密就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节(通常补00或者FF,根据实际要求不同)进行计算,之后按照顺序将计算所得的数据连在一起即可。

这里有个问题就是为什么要进行数据补位?主要原因是DES算法加解密时要求数据必须为8个字节。

二、ECB模式

DES ECB(电子密本方式)其实非常简单,就是将数据按照8个字节一段进行DES加密或解密得到一段8个字节的密文或者明文,最后一段不足8个字节,按照需求补足8个字节进行计算,之后按照顺序将计算所得的数据连在一起即可,各段数据之间互不影响。

三、CBC模式

DES CBC(密文分组链接方式)有点麻烦,它的实现机制使加密的各段数据之间有了联系。其实现的机理如下:

加密步骤如下:

1)首先将数据按照8个字节一组进行分组得到D1D2......Dn(若数据不是8的整数倍,用指定的PADDING数据补位)

2)第一组数据D1与初始化向量I异或后的结果进行DES加密得到第一组密文C1(初始化向量I为全零)

3)第二组数据D2与第一组的加密结果C1异或以后的结果进行DES加密,得到第二组密文C2

4)之后的数据以此类推,得到Cn

5)按顺序连为C1C2C3......Cn即为加密结果。

解密是加密的逆过程,步骤如下:

1)首先将数据按照8个字节一组进行分组得到C1C2C3......Cn

2)将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)

3)将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D2

4)之后依此类推,得到Dn

5)按顺序连为D1D2D3......Dn即为解密结果。

这里注意一点,解密的结果并不一定是我们原来的加密数据,可能还含有你补得位,一定要把补位去掉才是你的原来的数据。

*** DES算法*/public class DES {   /**   *   * @return DES算法密钥   */   public static byte[] generateKey() {        try {            // DES算法要求有一个可信任的随机数源            SecureRandom sr = new SecureRandom();            // 生成一个DES算法的KeyGenerator对象            KeyGenerator kg = KeyGenerator.getInstance("DES");            kg.init(sr);            // 生成密钥            SecretKey secretKey = kg.generateKey();            // 获取密钥数据            byte[] key = secretKey.getEncoded();            return key;        } catch (NoSuchAlgorithmException e) {            System.err.println("DES算法,生成密钥出错!");            e.printStackTrace();        }        return null;   }   /**   * 加密函数   *   * @param data   *            加密数据   * @param key   *            密钥   * @return 返回加密后的数据   */   public static byte[] encrypt(byte[] data, byte[] key) {        try {            // DES算法要求有一个可信任的随机数源            SecureRandom sr = new SecureRandom();            // 从原始密钥数据创建DESKeySpec对象            DESKeySpec dks = new DESKeySpec(key);            // 创建一个密匙工厂,然后用它把DESKeySpec转换成            // 一个SecretKey对象            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = keyFactory.generateSecret(dks);            // using DES in ECB mode            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");            // 用密匙初始化Cipher对象            cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);            // 执行加密操作            byte encryptedData[] = cipher.doFinal(data);            return encryptedData;        } catch (Exception e) {            System.err.println("DES算法,加密数据出错!");            e.printStackTrace();        }        return null;   }   /**   * 解密函数   *   * @param data   *            解密数据   * @param key   *            密钥   * @return 返回解密后的数据   */   public static byte[] decrypt(byte[] data, byte[] key) {        try {            // DES算法要求有一个可信任的随机数源            SecureRandom sr = new SecureRandom();            // byte rawKeyData[] = /* 用某种方法获取原始密匙数据 */;            // 从原始密匙数据创建一个DESKeySpec对象            DESKeySpec dks = new DESKeySpec(key);            // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成            // 一个SecretKey对象            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = keyFactory.generateSecret(dks);            // using DES in ECB mode            Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");            // 用密匙初始化Cipher对象            cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);            // 正式执行解密操作            byte decryptedData[] = cipher.doFinal(data);            return decryptedData;        } catch (Exception e) {            System.err.println("DES算法,解密出错。");            e.printStackTrace();        }        return null;   }   /**   * 加密函数   *   * @param data   *            加密数据   * @param key   *            密钥   * @return 返回加密后的数据   */   public static byte[] CBCEncrypt(byte[] data, byte[] key, byte[] iv) {        try {            // 从原始密钥数据创建DESKeySpec对象            DESKeySpec dks = new DESKeySpec(key);            // 创建一个密匙工厂,然后用它把DESKeySpec转换成            // 一个SecretKey对象            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = keyFactory.generateSecret(dks);            // Cipher对象实际完成加密操作            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");            // 若采用NoPadding模式,data长度必须是8的倍数            // Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");            // 用密匙初始化Cipher对象            IvParameterSpec param = new IvParameterSpec(iv);            cipher.init(Cipher.ENCRYPT_MODE, secretKey, param);            // 执行加密操作            byte encryptedData[] = cipher.doFinal(data);            return encryptedData;        } catch (Exception e) {            System.err.println("DES算法,加密数据出错!");            e.printStackTrace();        }        return null;   }   /**   * 解密函数   *   * @param data   *            解密数据   * @param key   *            密钥   * @return 返回解密后的数据   */   public static byte[] CBCDecrypt(byte[] data, byte[] key, byte[] iv) {        try {            // 从原始密匙数据创建一个DESKeySpec对象            DESKeySpec dks = new DESKeySpec(key);            // 创建一个密匙工厂,然后用它把DESKeySpec对象转换成            // 一个SecretKey对象            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");            SecretKey secretKey = keyFactory.generateSecret(dks);            // using DES in CBC mode            Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");            // 若采用NoPadding模式,data长度必须是8的倍数            // Cipher cipher = Cipher.getInstance("DES/CBC/NoPadding");            // 用密匙初始化Cipher对象            IvParameterSpec param = new IvParameterSpec(iv);            cipher.init(Cipher.DECRYPT_MODE, secretKey, param);            // 正式执行解密操作            byte decryptedData[] = cipher.doFinal(data);            return decryptedData;        } catch (Exception e) {            System.err.println("DES算法,解密出错。");            e.printStackTrace();        }        return null;   }   public static void main(String[] args) {        try {            byte[] key = "11111111".getBytes();            byte[] iv = "22222222".getBytes();            byte[] data = DES.encrypt("ebc mode test".getBytes(), key);            System.out.print("EBC mode:");            System.out.println(new String(DES.decrypt(data, key)));            System.out.print("CBC mode:");            data = DES.CBCEncrypt("cbc mode test".getBytes(), key, iv);            System.out.println(new String(DES.CBCDecrypt(data, key, iv)));                    } catch (Exception e) {            e.printStackTrace();        }   }}

DES的几种填补方式

DES是对64位数据的加密算法,如数据位数不足64位的倍数,需要填充,补充到64位的倍数。

NoPadding

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

PKCS5Padding

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

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

因为DES是一种block cipher,一个block要8个字节,所以要加密的东西要分成8字节的整数倍,不足的就填充。

PKCS5Padding这种填充,填的字节代表所填字节的总数:

比如差三个字节的话填为 @@@@@333

差7个字节就填为 @7777777

没有差就填 88888888

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/431871.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可访问性不一致的原因与解决方法

出现原因,其中一个是返回参数的访问级别小于函数的访问级别,也就是说当定义一个返回参数的方法的时候,如果返回参数的访问级别低于方法的访问级别,此时就会出现这样的错误。如果返回的参数不能被访问,那么定义的返回的方法也是错误…

jQuery 事件 - bind() 方法

定义和用法 bind() 方法为被选元素添加一个或多个事件处理程序&#xff0c;并规定事件发生时运行的函数。 实例1&#xff08;一个事件&#xff09; 记得把js引用地址换掉 当点击鼠标时&#xff0c;隐藏或显示 p 元素&#xff1a; <html><head><script type"…

java 圆形按钮,如何在Java中创建圆形的JButton?

I want to create rounded JButton in Java...For that I use rounded image and placed that image on button but I didnt get rounded button..please any one can tell how to create rounded button in Java like show in below figure..thanks in advance.....解决方案If…

Python学习 Day 3 字符串 编码 list tuple 循环 dict set

字符串和编码 字符 ASCII Unicode UTF-8 A 1000001 00000000 01000001 1000001 中 x 01001110 00101101 11100100 10111000 10101101 格式化 在Python中&#xff0c;采用的格式化方式和C语言是一致的&#xff0c;用%实现&#xff0c;举例如下&#xff1a; >>&…

java hibernate dto_java – 正确使用Entity和DTO在Restful Web服务中...

有很多文章指出使用JPA / hibernate不需要使用DTO同样在article由SO成员Bohzo我很少需要阅读DTO甚至在articles中反对暴露实体声明当实体没有任何行为时(当它们是POJO时)不需要具有DTO,如在贫血域模型中那样假设有一个Entity类class Department{List employees //lazily loaded…

构建之法现代软件概述

软件工程&#xff1a;就是用科学的知识工程和技术原理来定义&#xff0c;开发&#xff0c;维护软件的一门学科。软件工程的目标&#xff1a;付出较低开发成本&#xff1b;达到要求的功能&#xff1b;取得较好的性能&#xff1b;开发的软件易于移植&#xff1b;只需较低的维护费…

java 高飞_高飞(土木与水利工程学院)老师 - 合肥工业大学

高飞高飞老师的简历姓名:高飞 性别:男 出生年月:1962.11最终学位:硕士 毕业院校:合肥工业大学职称:教授 职务:副院长电话:0551-2901441,13705510744E-mail:gaofeihfut.edu.cn现从事专业:测绘科学与技术社会团体任职:1.全国高等学校测绘学科教学指导委员会,委员;2.中国测绘学会工…

Python_03-数据类型

1.1 数据类型 基本数据类型&#xff1a;字符串&#xff0c;整数&#xff0c;浮点数&#xff0c;布尔型 集合类型&#xff1a;列表&#xff08;list), 元组&#xff08;tuple), 字典&#xff08;dictionary或hash) 列表&#xff08;list&#xff09;的定义&#xff1a; aList …

java串口监听超时_从串口读取时如何实现read()的超时(C / C)

有几种可能的方法 . 如果程序最终将定时多个i / o操作&#xff0c; select() 是明智的选择 .但是&#xff0c;如果唯一的输入来自此i / o&#xff0c;则选择非阻塞i / o和时序是一种简单的方法 . 我已经将它从单字符i / o扩展到多字符&#xff0c;使其成为一个更普遍的完整示例…

64位操作系统下IIS报“试图加载格式不正确的程序”错误

缘由&#xff1a;在64位操作系统下IIS发布32位的项目&#xff0c;报“项目依赖的dll无法读取&#xff0c;试图加载格式不正确的程序”错误。 原因&#xff1a;程序集之间的通讯要么全是64位环境下的&#xff0c;要么全是32位环境下的。不能混编访问。不然会出现“试图加载格式不…

java训练_Java练习

package exec;/*2.根据圆柱体的半径和高&#xff0c;使用下面的公式&#xff0c;计算圆柱的体积面积半径*半径*π体积面积*高 */public class work01 {public static void main(String[] args) {// TODO Auto-generated method stub//定义圆柱的高和半径&#xff0c;面积&#…

jwPlayer为js预留的回调方法

参考地址&#xff1a;http://www.cnblogs.com/lori/archive/2014/05/05/3709459.html 应用场合 播放时记录当前视频的时间&#xff0c;播放完成时写入完成的时间&#xff0c;像这些功能&#xff0c;我们都可以通过事件回调的方法解决&#xff0c;即为events属性赋相应的值&…

新手学java7编程_新手学Java 7编程:面向对象程序设计

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼面向对象程序设计Java的核心是面向对象程序设计(OOP)。面向对象方法论与Java是密不可分的&#xff0c;而Java所有的程序至少在某种程度上都是面向对象的。因为OOP对Java的重要性&#xff0c;所以在开始编写一个哪怕是很简单的Java程…

脚本两则--用于快速部署HADOOP,SPARK这些(特别是VM虚拟机模板部署出来的)。。...

感觉可能只是适合我自己的部署习惯吧&#xff0c;且只针对CENTOS6及以下版本&#xff0c;以后有时间&#xff0c;可能还是要改进。。 1&#xff0c;从VM的模块产生的虚拟机&#xff0c;如何快速搞定网络配置&#xff1f; #!/bin/bash#usage:./init_cdh_sys.sh hostname hostip …

java值参_JAVA赋值和传参理解

作者&#xff1a;Intopass链接&#xff1a;https://www.zhihu.com/question/31203609/answer/50992895来源&#xff1a;知乎著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。第一个例子&#xff1a;基本类型void foo(int value) {value 100;}…

随机系列生成算法(随机数生成)

1、问题描述 给定一个正整数n&#xff0c;需要输出一个长度为n的数组&#xff0c;数组元素是随机数&#xff0c;范围为0 – n-1&#xff0c;且元素不能重复。比如 n 3 时&#xff0c;需要获取一个长度为3的数组&#xff0c;元素范围为0-2。 2、准备 首先&#xff0c;让我们先构…

java list 分组_Java 将List中的实体类按照某个字段进行分组并存

1、JDK1.8之前&#xff1a;假设有实体类User&#xff0c;里面有字段id&#xff0c;我们将相同id的User进行分组&#xff0c;并存放在Map中。(例子不是很恰当&#xff0c;但很能说明问题)public static void main(String[] args) {List list new ArrayList<>();list.add(…

UVa 11481 (计数) Arrange the Numbers

居然没有往错排公式那去想&#xff0c;真是太弱了。 先在前m个数中挑出k个位置不变的数&#xff0c;有C(m, k)种方案&#xff0c;然后枚举后面n-m个位置不变的数的个数i&#xff0c;剩下的n-k-i个数就是错排了。 所以这里要递推一个组合数和错排数。 顺便再复习一下错排递推公式…

java httpclient 关闭_【Java系列007】HttpClient调用:你考虑过关闭连接、并发了吗?...

你好&#xff01;我是miniluo&#xff0c;今天和你分享使用HttpClient过程中&#xff0c;未考虑释放连接和并发导致的坑。HttpClient在项目中还是比较常见的&#xff0c;主要都是通过GET或POST请求第三方以获取响应结果。前段时间还了解到也有企业用它来做爬虫。下面我们就从两…

统计学中【矩】的概念

这个问题要从物理学、统计学和语源学三个角度来回答。矩&#xff0c;英文为moment。历史上出现的顺序是物理moment -> 统计moment -> 数学moment&#xff0c;并且数学moment完全是对此的归纳&#xff0c;并不是起源。先整理一下历史&#xff1a;力矩这个概念最早是由阿基…