-
2020-01-18 18:05:11
密钥
首先这个类中要有一个密码作为密钥,是加密解密的凭据,长度为8的倍数。
private static String password = "ZNMJJWEB";
加密方法
参数为数据源,返回加密后的数据
public static String encrypt(String data) { try { byte[] datasource = data.getBytes("UTF-8"); SecureRandom random = new SecureRandom();//获得安全随机数,DES算法要求有一个可信任的随机数源 DESKeySpec desKey = new DESKeySpec(password.getBytes("UTF-8")); // 创建一个密匙工厂,然后用它把DESKeySpec转换成一个SecretKey对象 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成加密操作 Cipher cipher = Cipher.getInstance("DES"); // 用密匙初始化Cipher对象 cipher.init(Cipher.ENCRYPT_MODE, securekey, random); // 现在,获取数据并加密 // 正式执行加密操作 byte[] enc = cipher.doFinal(datasource); return APPub.StringUtils.ByteToHexString(enc);//返回加密后数据 } catch (Throwable e) { e.printStackTrace(); } return null; }
解密方法
参数是数据源,返回加密前的原始数据
public static String decrypt(String Data) { String Rlt = ""; try { byte[] datasource = APPub.StringUtils.HexStringToByte(Data);// Data.getBytes("UTF-8"); // DES算法要求有一个可信任的随机数源 SecureRandom random = new SecureRandom(); // 创建一个DESKeySpec对象 DESKeySpec desKey = new DESKeySpec(password.getBytes("UTF-8")); // 创建一个密匙工厂 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); // 将DESKeySpec对象转换成SecretKey对象 SecretKey securekey = keyFactory.generateSecret(desKey); // Cipher对象实际完成解密操作 Cipher cipher = Cipher.getInstance("DES"); // 用密匙初始化Cipher对象 cipher.init(Cipher.DECRYPT_MODE, securekey, random); // 真正开始解密操作 byte[] dec = cipher.doFinal(datasource); return new String(cipher.doFinal(datasource), "UTF-8"); } catch (Exception e) { e.printStackTrace(); } return Rlt; }
博客资料:
DES加密更多相关内容 -
DES加密算法JAVA实现(带简单界面)
2019-06-09 15:34:58使用java实现的DES算法加密,带有界面。DES加密算法JAVA实现(带简单界面) -
des加密算法java实现
2016-04-17 10:12:41DES加解密算法,java实现,可运行! -
JAVA实现des加密算法 实例
2018-06-01 22:36:39项目中需要用到这个,后来到网上找了不少,但算出来结果不对.这个是经过个人验证的.有类似需要的可以考虑 -
DES_DES加密算法JAVA实现_
2021-10-03 10:11:33这是一个用Java实现的DES高级加密算法的源代码 -
DES对称加密算法Java实现
2018-01-06 23:31:16DES算法为密码体制中的对称密码体制,是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密用的是同一个算法。 这里以Java代码实现DES算法。 -
DES数据加密算法Java实现
2014-09-20 22:41:32DES数据加密算法,网络安全中较为基础的算法之一,用于学习交流使用 -
java实现的DES加密算法详解
2020-08-30 03:34:45主要介绍了java实现的DES加密算法,结合实例形式详细分析了java实现DES加密操作的原理、实现技巧与相关注意事项,需要的朋友可以参考下 -
Java最简单的DES加密算法实现案例
2020-08-30 06:58:44下面小编就为大家带来一篇Java最简单的DES加密算法实现案例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 -
三重DES加密算法JAVA实现
2022-04-14 22:29:56三重DES加密实验实验环境
Eclipse
实验步骤
利用Java开发一个文件加密软件,使之能够对任何文件通过三重DES 加密,加密密钥key1、key2、key3由用户输入的24个字符构成,加密后生成的文件为“原文件名.tdes”。
单击“浏览...”按钮可选择加密或解密的文件。然后输人24个字符的密钥,程序自动取前8个字符为keyl,中间8个字符为key2,最后8个字符为key3。之后,单击“加密”或“解密”按钮,即可进行加密或解密。注意,在对文件解密时,在文件选择文本框里的文件扩展名必须为.tdes。
源代码
import java.awt.*; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import javax.crypto.spec.DESedeKeySpec; import javax.swing.*; import java.awt.event.*; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class FileEncrypter extends JFrame{ public static void main(String[] args) { FileEncrypter fe = new FileEncrypter(); fe.show(); } FileEncrypter(){ this.setSize(550,200); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setLocation(400,300); this.setTitle("3DES加密工具"); Container c = this.getContentPane(); c.setLayout(new FlowLayout()); JLabel label = new JLabel("选择文件"); c.add(label); final JTextField fileText = new JTextField(35); c.add(fileText); JButton chooseButton = new JButton("浏览"); chooseButton.addActionListener(new ActionListener(){ //浏览按钮的点击事件监听 @Override public void actionPerformed(ActionEvent e){ JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); int result = chooser.showOpenDialog(null); if(result == JFileChooser.APPROVE_OPTION){ //获得文件绝对路径 String path = chooser.getSelectedFile().getAbsolutePath(); fileText.setText(path); } } }); c.add(chooseButton); JLabel label2 = new JLabel("秘钥(24个字符):"); c.add(label2); final JTextField keyText = new JTextField(35); c.add(keyText); JButton jbe = new JButton("加密"); c.add(jbe); jbe.addActionListener(new ActionListener(){ //以下编写"加密"按钮的监听和事件 @Override public void actionPerformed(ActionEvent event) { String wenjian,miyao; wenjian = fileText.getText(); miyao = keyText.getText(); if("".equals(wenjian) || wenjian == null){ JOptionPane.showMessageDialog(null,"请选择文件!","提示",JOptionPane.OK_OPTION); }else{ if("".equals(miyao) || miyao == null){ JOptionPane.showMessageDialog(null,"请输入24字节秘钥!","提示",JOptionPane.OK_OPTION); }else{ if(miyao.length() != 24){ JOptionPane.showMessageDialog(null, "秘钥必须为24字节!","提示",JOptionPane.OK_OPTION); }else{ //将三个秘钥分别 存入三个字节型数组中 byte[] key1 = miyao.substring(0,8).getBytes(); byte[] key2 = miyao.substring(8,16).getBytes(); byte[] key3 = miyao.substring(16,24).getBytes(); File file = new File(wenjian); //读取明文并存入字节型数组plain中 byte[] plain = bytefromfile(file); try { byte[] bytOut = encryptByDES(encryptByDES(encryptByDES(plain,key1),key2),key3); String fileOut = wenjian + ".tdes"; FileOutputStream fos = new FileOutputStream(fileOut); for(int i = 0; i < bytOut.length; i++){ fos.write((int)bytOut[i]); } fos.close(); JOptionPane.showMessageDialog(null,"加密成功!","提示",JOptionPane.INFORMATION_MESSAGE); } catch (Exception e) { //e.printStackTrace(); JOptionPane.showMessageDialog(null,"加密失败!请检查文件或者秘钥","提示",JOptionPane.OK_OPTION); } } } } } }); JButton jbD = new JButton("解密"); c.add(jbD); //解密按钮点击事件 jbD.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { String wenjian,wenjian1,miyao; wenjian = fileText.getText(); miyao = keyText.getText(); if("".equals(wenjian) || wenjian == null){ JOptionPane.showMessageDialog(null,"请选择文件!","提示",JOptionPane.OK_OPTION); return; } if(wenjian.substring(wenjian.length() - 5).toLowerCase().equals(".tdes")){ if(miyao.length()!=24){ JOptionPane.showMessageDialog(null, "秘钥必须为24字节!","提示",JOptionPane.OK_OPTION); return; }else{ wenjian1 = wenjian.substring(0,wenjian.length() - 5); JFileChooser chooser = new JFileChooser(); chooser.setCurrentDirectory(new File(".")); //用户指定要保存的文件的位置 chooser.setSelectedFile(new File(wenjian1)); int ret = chooser.showSaveDialog(null); if(ret == 0){ byte[] key1 = miyao.substring(0,8).getBytes(); byte[] key2 = miyao.substring(8,16).getBytes(); byte[] key3 = miyao.substring(16,24).getBytes(); File file = new File(wenjian); //读取密文 byte[] miwen = bytefromfile(file); try{ //解密 byte[] bytOut = decryptByDES(decryptByDES(decryptByDES(miwen,key3),key2),key1); File fileOut = chooser.getSelectedFile(); fileOut.createNewFile(); FileOutputStream fos = new FileOutputStream(fileOut); for(int i = 0; i < bytOut.length; i++){ fos.write((int) bytOut[i]); } fos.close(); JOptionPane.showMessageDialog(null, "解密成功!","提示",JOptionPane.INFORMATION_MESSAGE); }catch (Exception e) { JOptionPane.showMessageDialog(null, "解密失败!请检查文件或秘钥","提示",JOptionPane.OK_OPTION); } } } }else{ JOptionPane.showMessageDialog(null, "不是合法的加密文件!","提示",JOptionPane.OK_OPTION); } } }); } //从输入的文件中读取字节,保存于TextofFile数组中,并返回 private byte[] bytefromfile(File filein){ byte[] TextofFile = new byte[(int)filein.length()]; try{ FileInputStream fin = new FileInputStream(filein); for(int i = 0; i < filein.length(); i++){ TextofFile[i] = (byte)fin.read(); } fin.close(); }catch(IOException e){ e.printStackTrace(); } return TextofFile; } //根据输入的明文进行加密 private byte[] encryptByDES(byte[] bytP, byte[] bytKey) throws Exception{ DESKeySpec desKS = new DESKeySpec(bytKey); SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); SecretKey sk = skf.generateSecret(desKS); Cipher cip = Cipher.getInstance("DES"); cip.init(Cipher.ENCRYPT_MODE, sk); return cip.doFinal(bytP); } //根据密文和秘钥进行解密 private byte[] decryptByDES(byte[] bytE, byte[] bytKey) throws Exception{ DESKeySpec desKS = new DESKeySpec(bytKey); SecretKeyFactory skf = SecretKeyFactory.getInstance("DES"); SecretKey sk = skf.generateSecret(desKS); Cipher cip = Cipher.getInstance("DES"); cip.init(Cipher.DECRYPT_MODE, sk); return cip.doFinal(bytE); } }
运行截图
原文:
加密后:
对加密后的文件解密
-
使用java自带des加密算法实现文件加密和字符串加密
2020-09-04 14:09:44主要介绍了使用java自带des加密算法实现文件加密和字符串加密的示例,需要的朋友可以参考下 -
DES算法Java实现源代码
2019-04-08 17:36:47DES算法Java实现源代码;网络安全技术及应用;java图形界面实现 -
DES加密算法【Java实现】
2021-04-13 22:20:55DES是一个分组加密算法,以64位为分组对数据加密(每次处理固定长度的数据段,称之为分组)。如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。 DES的明文长为64位,密钥长64位,但密钥事实上是...简单介绍
- DES算法为密码体制中的对称密码体制,又被称为美国数据加密标准,2000年以前一直是业界的标准。
- DES是一个分组加密算法,以64位为分组对数据加密(每次处理固定长度的数据段,称之为分组)。如果加密的数据长度不是64位的倍数,可以按照某种具体的规则来填充位。
- DES的明文长为64位,密钥长64位,但密钥事实上是56位参与DES运算(第8、16、24、32、40、48、56、64位是校验位,使得每个密钥都有奇数个1),分组后的明文组和56位的密钥按位替代或交换的方法形成密文组。
- DES算法具体通过对明文进行一系列的排列和替换操作来将其加密。DES 解密算法与加密算法完全相同,只需要将子密钥的使用顺序反过来就行了。
算法流程
DES加密算法流程总体如上图所示,主体内容为中间操作(包括密码函数f和异或操作)循环16次。
DES加密算法五个最值得注意的部分为:
- IP置换;
- 子密钥 Ki 的获取;
- 密码函数 f ;
- 逆IP置换;
- 其他;
IP置换
IP(initial permutation 初始排列)是一个 8x8 的置换表:
// Replacement Table(RT) final int RT_IP[] = { 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 };
IP置换表的含义为:原来的58位现在排在第一位,50位排在第二位…以此类推【下文所有置换都是这个含义】。注:该过程输入是64位的分组,IP置换以后得到的是一个 64 位的输出。
子密钥 Ki 的获取
-
根据密钥选择置换表
RT_Key
,将 64 位输入密钥变成 56 位。(去掉了奇偶校验位) -
将
RT_Key
置换得到的 56 位密钥(其实这也是一种压缩置换,特指去掉了奇偶校验位的过程),分为前28位 C0 和后28位 D0,分别对它们进行循环左移,C0左移得到 C1,D0 左移得到 D1。 -
将 C1 和 D1 合并,然后通过
RT_Compress
表进行压缩置换,得到当前这一轮的 48 位子密钥 K1 。 -
然后对 C1 和 D1 进行左移和压缩置换,获取下一轮的子密钥……一共进行16轮,得到 16 个 48 位的子密钥。
这部分需要用到的置换表和移动位数记录等常量如下:
// 密钥选择(置换)表,64位密钥去掉校验位,选择剩下的56位作为新的密钥。可以发现,去掉校验位的同时还打乱了顺序 final int RT_Key[] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; // 压缩置换表,将56位密钥压缩成48位子密钥,同时打乱顺序 final int RT_Compress[] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; // 每轮左移的位数 final int shiftBits[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
密码函数 f
密码函数f(R, K)接受两个输入:32 位的R数据(明文的右半部分)和 48 位的子密钥(Ki)。然后:
-
通过表 E 进行扩展置换,将输入的 32 位数据扩展为 48 位;
-
将扩展后的 48 位数据与 48 位的子密钥进行异或运算;
-
将异或得到的 48 位数据分成 8 个 6 位的块,每一个块通过对应的一个 S 表产生一个 4 位的输出。其中,每个 S 表都是 4 行 16 列。具体的置换过程如下:把 6 位输入中的第 1 位和第 6 位取出来行成一个两位的二进制数 x ,作为 Si 表中的行数(0~3);把 6 位输入的中间 4 位构成另外一个二进制数 y,作为 Si 表的列数(0~15);查出 Si 表中 x 行 y 列所对应的整数,将该整数转换为一个 4 位的二进制数。
-
把通过 S 表置换得到的 8 个 4 位连在一起,形成一个 32 位的数据。然后将该 32 位数据通过表 P 进行置换(称为P-置换),置换后得到一个仍然是 32 位的结果数据,这就是f(R, K)函数的输出。
这部分用到了扩展置换表RT_E,8个S表以及P-置换表(RT_P),如下:
// 扩展置换表 RT_E,将32位扩展至48位 final int RT_E[] = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; // S盒,每个S盒Si是4x16的置换表,6位 -> 4位 final int S_BOX[][][] ={ { {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7}, {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8}, {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0}, {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13} }, { {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10}, {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5}, {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15}, {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9} }, { {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8}, {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1}, {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7}, {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12} }, { {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15}, {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9}, {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4}, {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14} }, { {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9}, {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6}, {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14}, {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3} }, { {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11}, {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8}, {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6}, {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13} }, { {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1}, {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6}, {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2}, {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12} }, { {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7}, {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2}, {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8}, {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11} } }; // P置换,32位 -> 32位 final int RT_P[] = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
逆IP置换
合并 L16 和 R16 得到一个 64 位的数据,再经过尾置换后得到的就是 64 位的密文。注意:要将 L16和 R16 合并成 R16L16(即左右互换)。逆IP置换表如下:
// 逆IP置换表 final int RT_InverseIP [] = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25};
注意:逆IP置换就是IP置换的反操作,A经过IP置换得到B,那B经过逆IP置换就可以得到A。逆IP置换表中第一个数是40,而IP置换表中,第40个元素为1。
现在我们可以回到本文的开头,去看看 DES 算法的整体流程图,思路就已经很清楚了。
其他
- 异或运算(图中的⊕符号)是指两个多位比特流之间的异或,操作为:对比特流逐位采用异或运算再拼接起来。异或运算规则为:[相同为0,不同为1,即1 ^ 1 = 0;0 ^ 0 = 0;1 ^ 0 = 1]
代码实现
package lesson; public class DES { // Replacement Table(RT)IP置换表 final static int[] RT_IP = { 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 }; // 密钥选择(置换)表,64位密钥去掉校验位,选择剩下的56位作为新的密钥。可以发现,去掉校验位的同时还打乱了顺序 final static int[] RT_Key = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; // 压缩置换,将56位密钥压缩成48位子密钥 final static int[] RT_Compress = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10, 23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2, 41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48, 44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32}; // 每轮左移的位数 final static int[] shiftBits = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1}; // 扩展置换表 RT_E,将32位扩展至48位 final static int[] RT_E = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1}; // S盒,每个S盒Si是4x16的置换表,6位 -> 4位 final static int[][][] S_BOX ={ { {14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7}, {0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8}, {4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0}, {15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13} }, { {15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10}, {3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5}, {0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15}, {13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9} }, { {10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8}, {13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1}, {13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7}, {1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12} }, { {7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15}, {13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9}, {10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4}, {3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14} }, { {2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9}, {14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6}, {4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14}, {11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3} }, { {12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11}, {10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8}, {9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6}, {4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13} }, { {4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1}, {13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6}, {1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2}, {6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12} }, { {13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7}, {1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2}, {7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8}, {2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11} } }; // P置换,32位 -> 32位 final static int[] RT_P = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 }; // 逆IP置换表 final static int[] RT_InverseIP = {40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31, 38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29, 36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27, 34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25}; /**********************************************************************/ /* */ /* 下面是DES算法实现 */ /* */ /**********************************************************************/ //生成16个子密钥 public static StringBuffer[] GenerateSubKey(StringBuffer str, boolean flag) throws Exception{ if(str.length()!=64){ throw new Exception("输入密钥长度不是64位!"); } else { //密钥选择 StringBuffer choosedKey = new StringBuffer(); for (int i = 0; i < RT_Key.length; i++) { choosedKey.append(str.charAt(RT_Key[i]-1)); } //拆分密钥 // System.out.println("choosedKey.length():"+choosedKey.length()); StringBuffer leftString = new StringBuffer(choosedKey.substring(0,28)); StringBuffer rightString = new StringBuffer(choosedKey.substring(28,56)); //16次循环得到16个子密钥 StringBuffer[] res = new StringBuffer[16]; for (int i = 0; i < 16; i++) { int shiftBit=shiftBits[i]; //两部分密钥分别左移 StringBuffer temp_left=new StringBuffer(leftString); StringBuffer temp_right=new StringBuffer(rightString); for (int j = 0; j < leftString.length(); j++) { if(j-shiftBit<0){ leftString.setCharAt(j,temp_left.charAt(j-shiftBit+28)); rightString.setCharAt(j,temp_right.charAt(j-shiftBit+28)); }else{ leftString.setCharAt(j,temp_left.charAt(j-shiftBit)); rightString.setCharAt(j,temp_right.charAt(j-shiftBit)); } } //压缩置换 StringBuffer temp=new StringBuffer(leftString); StringBuffer input = temp.append(rightString); StringBuffer subKey = new StringBuffer(); for (int k = 0; k < RT_Compress.length; k++) { subKey.append(input.charAt(RT_Compress[k]-1)); } res[i]=subKey; } StringBuffer[] res_reverse = new StringBuffer[16]; for (int i = 0; i < res.length; i++) { res_reverse[i]=res[res.length-i-1]; } return flag?res:res_reverse; } } //IP置换 public static StringBuffer IPReplacement(StringBuffer str){ StringBuffer res = new StringBuffer(); for (int i = 0; i < RT_IP.length; i++) { res.append(str.charAt(RT_IP[i]-1)); } return res; } //执行F密码函数 public static StringBuffer function(StringBuffer subKey, StringBuffer R) throws Exception { //1.扩展置换 StringBuffer extendedString = new StringBuffer(); for (int i = 0; i < RT_E.length; i++) { extendedString.append(R.charAt(RT_E[i]-1)); } //2.异或操作 StringBuffer xor = XOR(extendedString, subKey); if(xor.length()!=48){ throw new Exception("异或结果不等于48位!"); }else{ //3.S盒 StringBuffer S_output =new StringBuffer(); for (int i = 0; i < 8; i++) { //3.1 拆分为6位子串substring String substring = xor.substring(6 * i, 6 * (i+1)); //3.2 将substring取0,5位为x;其余4位为y【二进制转换】 int x=binaryToDecimal(substring.substring(0,1)+substring.substring(5,6)); int y=binaryToDecimal(substring.substring(1,5)); //3.3 从S盒取S[i][x][y]转化为4位输出 String s = Integer.toBinaryString(S_BOX[i][x][y]); StringBuffer stringBuffer = new StringBuffer(s); //3.4 如果输出未达到4位则往前补0,补齐4位 while(4-stringBuffer.length()!=0){ stringBuffer.insert(0,'0'); } S_output.append(stringBuffer); } //4.P盒 StringBuffer res = new StringBuffer(); for (int i = 0; i < RT_P.length; i++) { res.append(S_output.charAt(RT_P[i]-1)); } return res; } } //执行异或操作 public static StringBuffer XOR(StringBuffer L, StringBuffer output) throws Exception{ if(L.length()!=output.length()){ throw new Exception("两者长度不同,不能进行异或运算!"); }else{ StringBuffer res = new StringBuffer(L.length()); for (int i = 0; i < L.length(); i++) { int temp =0; if(L.charAt(i)!=output.charAt(i)){temp=1;} res.append(temp); } return res; } } //逆IP置换 public static StringBuffer ReverseIPReplacement(StringBuffer str){ StringBuffer res = new StringBuffer(); for (int i = 0; i < RT_InverseIP.length; i++) { res.append(str.charAt(RT_InverseIP[i]-1)); } return res; } //二进制转化为10进制 public static int binaryToDecimal(String str){ int len = str.length(); int res=0; for (int i = 0; i < len; i++) { res+=Integer.parseInt(String.valueOf(str.charAt(len-i-1)))*Math.pow(2,i); } return res; } //完整加密过程 public static StringBuffer Encryption(StringBuffer Plaintext, StringBuffer Key) throws Exception { //1.获取子密钥 StringBuffer[] subKeys =GenerateSubKey(Key,true); //2.IP置换 StringBuffer stringBuffer = IPReplacement(Plaintext); StringBuffer Leftstring = new StringBuffer(stringBuffer.substring(0, 32)); StringBuffer Rightstring = new StringBuffer(stringBuffer.substring(32,64)); //3.for循环16轮 for (int i = 0; i < 16; i++) { //3.1 f函数 StringBuffer f_output=function(subKeys[i],Rightstring); //3.2 异或 StringBuffer temp=XOR(Leftstring,f_output); //3.3 更新Li和Ri Leftstring=Rightstring; Rightstring=temp; } //4.左右互换 StringBuffer res = Rightstring.append(Leftstring); //5.逆IP置换 res=ReverseIPReplacement(res); return res; } //完整解密过程 public static StringBuffer Decryption(StringBuffer Plaintext, StringBuffer Key) throws Exception { //1.获取子密钥 StringBuffer[] subKeys =GenerateSubKey(Key,false); //2.IP置换 StringBuffer stringBuffer = IPReplacement(Plaintext); StringBuffer Leftstring = new StringBuffer(stringBuffer.substring(0, 32)); StringBuffer Rightstring = new StringBuffer(stringBuffer.substring(32,64)); //3.for循环16轮 for (int i = 0; i < 16; i++) { //3.1 f函数 StringBuffer f_output=function(subKeys[i],Rightstring); //3.2 异或 StringBuffer temp=XOR(Leftstring,f_output); //3.3 更新Li和Ri Leftstring=Rightstring; Rightstring=temp; } //4.左右互换 StringBuffer res = Rightstring.append(Leftstring); //5.逆IP置换 res=ReverseIPReplacement(res); return res; } /**********************************************************************/ /* */ /* 下面是测试代码 */ /* */ /**********************************************************************/ // a) 使用同一密钥,对两组明文进行加密和解密。 // 64位密钥: // 00000010 10010110 01001000 11000100 00111000 00110000 00111000 01100100 // // 64位明文块1: // 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 // // 64位明文块2(与明文块1仅有一位的不同): // 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 // // 输出两个密文块的二进制流,统计两个密文块间不同数据位的数量。 // // b) 对同一段明文,使用不同密钥进行加密和解密操作。 // 64位密钥1: // 11100010 11110110 11011110 00110000 00111010 00001000 01100010 11011100 // // 64位密钥2(与密钥1仅有一位的不同): // 01100010 11110110 11011110 00110000 00111010 00001000 01100010 11011100 // // 明文: // 01101000 10000101 00101111 01111010 00010011 01110110 11101011 10100100 // // 输出两个密文块的二进制流,统计两个密文块间不同数据位的数量。 public static void main(String[] args) throws Exception { System.out.println(); System.out.println("a):使用同一密钥,对两组明文进行加密"); String key ="00000010 10010110 01001000 11000100 00111000 00110000 00111000 01100100"; String plaintext_1 ="00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000"; String plaintext_2 ="10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000"; StringBuffer Key= new StringBuffer(key.replaceAll(" ","")); StringBuffer Plaintext_1= new StringBuffer(plaintext_1.replaceAll(" ","")); StringBuffer Plaintext_2= new StringBuffer(plaintext_2.replaceAll(" ","")); StringBuffer Ciphertext_1 = Encryption(Plaintext_1, Key); StringBuffer Ciphertext_2 = Encryption(Plaintext_2, Key); System.out.println("密钥:"+Key); System.out.println("明文1:"+Plaintext_1); System.out.println("明文2:"+Plaintext_2); System.out.println("========================================================================"); System.out.println("密文1:"+Ciphertext_1); System.out.println("密文2:"+Ciphertext_2); Helper(Ciphertext_1, Ciphertext_2); System.out.println(); System.out.println("b):对同一段明文,使用不同密钥进行加密操作"); String key_1 ="11100010 11110110 11011110 00110000 00111010 00001000 01100010 11011100"; String key_2 ="01100010 11110110 11011110 00110000 00111010 00001000 01100010 11011100"; String plaintext ="01101000 10000101 00101111 01111010 00010011 01110110 11101011 10100100"; StringBuffer Key_1= new StringBuffer(key_1.replaceAll(" ","")); StringBuffer Key_2= new StringBuffer(key_2.replaceAll(" ","")); StringBuffer Plaintext= new StringBuffer(plaintext.replaceAll(" ","")); StringBuffer Ciphertext_b1 = Encryption(Plaintext_1, Key); StringBuffer Ciphertext_b2 = Encryption(Plaintext_2, Key); System.out.println("密钥1:"+Key_1); System.out.println("密钥2:"+Key_2); System.out.println("明文:"+Plaintext); System.out.println("==========================================================================="); System.out.println("密文1:"+Ciphertext_b1); System.out.println("密文2:"+Ciphertext_b2); Helper(Ciphertext_b1, Ciphertext_b2); System.out.println(); System.out.println("c):附加,对一个明文和密钥,先加密后解密"); StringBuffer Ciphertext_c = Encryption(Plaintext_1, Key); StringBuffer Plaintext_c = Decryption(Ciphertext_c, Key); System.out.println("明文:"+Plaintext_1); System.out.println("密钥:"+Key); System.out.println("==========================================================================="); System.out.println("加密后密文:"+Ciphertext_c); System.out.println("再解密后明文:"+Plaintext_c); } //帮助统计两个比特流之间不同的位数的数量 public static void Helper(StringBuffer str1,StringBuffer str2){ int res=0; for (int i = 0; i < str1.length(); i++) { int add=str1.charAt(i)==str2.charAt(i)?0:1; res+=add; } System.out.println("两个密文块间不同数据位的数量为:"+res); } }
结果图:
总结和思考
-
要多用StringBuffer(或StringBuilder)可以比 String 类更高效地处理字符串,如append操作不需要索引,setCharAt(index,‘s’) 可以更改某一个位置的char值(String做不到)。但是去除空格的时候还是得转成String类。
//去除字符串头尾的空格 System.out.println(str.trim()); //只去除字符串中的空格 System.out.println(str.replaceAll(" ", "")); //去除空白字符, \s 可以匹配空格、制表符、换页符等空白字符的其中任意一个 System.out.println(str.replaceAll("\\s*", ""));
-
DES加密解密就是密钥顺序反一下就好。Java函数没有默认参数(除非重载或者工厂方法实现…),所以生成子密钥需要手动输入参数flag,显式定义是子密钥在数组中顺排还是逆排(对应是加密还是解密)。
-
二进制与十进制间的转换
//10进制转化为二进制字符串 Integer.toBinaryString() //二进制转化为10进制,注意:幂次用Math.pow(2,i),而不要用2^i,后者相当于2+i public static int binaryToDecimal(String str){ int len = str.length(); int res=0; for (int i = 0; i < len; i++) { res+=Integer.parseInt(String.valueOf(str.charAt(len-i-1)))*Math.pow(2,i); } return res; }
-
Java不像C++那样有指针。在给对象初始化的时候,记得不要用对象直接赋值的方式,而应该new一个新对象
//压缩置换 StringBuffer temp=new StringBuffer(leftString); StringBuffer input = temp.append(rightString); //这里不能写成这样,这是把leftString指针给了temp,后面操作temp其实就是操作leftString StringBuffer temp=leftString; //这里也不能写成这样,这样leftString就会变长,因为append了一个rightString StringBuffer input = leftString.append(rightString);
-
什么是雪崩效益?根据以上结果,说明DES加密算法是否具有该性质:在密码学中,雪崩效应(Avalanche effect)指加密算法(尤其是块密码和加密散列函数)的一种理想属性。雪崩效应是指当输入发生最微小的改变(例如,反转一个二进制位)时,也会导致输出的剧变(如,输出中一半的二进制位发生反转)。在高品质的块密码中,无论密钥或明文的任何细微变化都应当引起密文的剧烈改变。DES有很好的雪崩效应,即使明文或密钥只更改了一位,密文也会有很大的差别(27位)。
参考文献
-
利用JAVA实现DES加密算法
2021-01-19 22:33:11虽然如此,在某些简单应用中,我们还是可以使用DES加密算法,本文简单讲解DES的JAVA实现。 JAVA实现加密代码有详细解释,不多废话。注意:DES加密和解密过程中,密钥长度都必须是8的倍数 代码如下: public byte[] ... -
DES加密算法JAVA代码
2008-12-02 14:17:59DES加密算法JAVA语言设计代码,是非常重要的加密技术 -
DES加密算法 java版
2014-03-27 08:32:15本DES算法是java语言写的,为了赚点积分下载自己需要的东西。谢谢大家!其实什么语言写是无所谓的,关键是一些基本模块的编写及相应的调用! -
DES加密算法详细原理以及Java代码实现
2021-02-12 15:48:01本周的密码学实验要求使用任意编程语言来实现des加密算法,于是我在查阅了相关资料后有了以下成果。首先,DES算法作为经典的分块密码(block cipher),其主要的实现过程由两部分组成,分别是密钥的生成以及明文的处理...本周的密码学实验要求使用任意编程语言来实现des加密算法,于是我在查阅了相关资料后有了以下成果。
首先,DES算法作为经典的分块密码(block cipher),其主要的实现过程由两部分组成,分别是密钥的生成以及明文的处理。
加密的大致流程如图所示
作为分块密码,密钥的输入以及明文的输入均为64位2进制数。
下面首先来说密钥的生成过程。
密钥处理部分如图所示
密钥的输入为64位,例如00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001,然后经过pc-1盒置换,会去除每一个8的倍数位(奇偶校验位)并打乱次序,将密钥变为56位。pc-1的置换表如下(框中的数字代表的是原密钥的位置,而不是数据)
1 57,49,41,33,25,17,9,1,2 58,50,42,34,26,18,10,2,3 59,51,43,35,27,19,11,3,4 60,52,44,36,63,55,47,39,5 31,23,15,7,62,54,46,38,6 30,22,14,6,61,53,45,37,7 29,21,13,5,28,20,12,4
也就是说,经过pc-1盒的置换原来第57位的1将会到第1位,原来49位的数据会到第2位,以此类推。在DES密钥加密的过程中,这种置换方式经常出现。
在经过了pc-1盒的置换后,原来56位的密钥会被均分为两组成为c0,d0。然后l0和d0会经过循环左移(left shift)的处理。
例如一串密钥为1010101,在经过一位的循环左移后会变成0101011,即循环左移几位,最左边的几位数据会紧接在后面,达到一种左移的效果。左移后的密钥块分别称为c1,d1。这时候,将c1以及d1组合起来,经过pc-2的置换(类似于pc-1)。
1 14,17,11,24,1,5,2 3,28,15,6,21,10,3 23,19,12,4,26,8,4 16,7,27,20,13,2,5 41,52,31,37,47,55,6 30,40,51,45,33,48,7 44,49,39,56,34,53,8 46,42,50,36,29,32
经过了pc-2盒的置换后,原本56位的密钥会变为48位。这个时候,第一个能够用于加密的子密钥k1就生成好了。在des算法密钥生成的过程中,一个主密钥会经过16轮的循环左移和pc-2置换,生成16个子密钥。循环左移的位数和轮次的关系如下表
后续子密钥的生成过程就是重复上面的过程,c1和d1再进行循环左移得到c2和d2,再经过pc-2盒置换得到k2,c2和d2再经过左移得到c3和d3经过pc-2盒得到k3.....经过这样的操作16轮,得到16个子密钥。密钥的生成过程大致如上,接下来来阐述明文的处理过程。
明文的处理流程大致如图所示。
首先,64位明文的输入需要经过初始置换,并把输出块分为L0,R0两部分,每部分32位。(有点类似于密钥初始化时的pc-1)置换规则如下:
1 58,50,42,34,26,18,10,2,2 60,52,44,36,28,20,12,4,3 62,54,46,38,30,22,14,6,4 64,56,48,40,32,24,16,8,5 57,49,41,33,25,17, 9,1,6 59,51,43,35,27,19,11,3,7 61,53,45,37,29,21,13,5,8 63,55,47,39,31,23,15,7
这个过程与pc-1阶段类似,置换后的第1位是原来的第58位,第2位是原来的第50位,以此类推。L0是置换后数据的前32位,R0是置换后的后32位。
经过了初始置换之后,R0会进依次进入E-box,S-box,P-box三个置换盒,进行下一步的处理。
E-box的处理过程如图示
E-box本质上是将原来32位的数据变为了48位,原理是将原来的32位输入以四位为一个单元分开,然后这个单元的第1位会复制到上一个单元的最后一位,这个单元的最后一位会变为下一个单元的第1位。看图可知,1234分块的第一位复制到了最后一块成为了第48位,第32位复制到了第1位成为了新数据组的第1位,具体过程如果还不明晰的话可以仔细看图解决。
在经过了E-box后,新的R0变为了48位,刚好与生成的密钥位数一致。这个时候,需要使用k1和新R0执行一次异或(相同记为0,不同记为1)操作,在异或操作结束后新的数据块会进入S-Box进行替代。
S-box会将48位的输入按照次序分为8组,分别进入8个子盒进行替代,每个盒的输入是6位,输出是4位。8个子盒原理如下:
S-box1
1 14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,2 0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,3 4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,4 15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13
S-box2
1 15,1,8,14,6,11,3,4,9,7,2,13,12,0,5,10,2 3,13,4,7,15,2,8,14,12,0,1,10,6,9,11,5,3 0,14,7,11,10,4,13,1,5,8,12,6,9,3,2,15,4 13,8,10,1,3,15,4,2,11,6,7,12,0,5,14,9
S-box3
1 10,0,9,14,6,3,15,5,1,13,12,7,11,4,2,8,2 13,7,0,9,3,4,6,10,2,8,5,14,12,11,15,1,3 13,6,4,9,8,15,3,0,11,1,2,12,5,10,14,7,4 1,10,13,0,6,9,8,7,4,15,14,3,11,5,2,12
S-box4
1 7,13,14,3,0,6,9,10,1,2,8,5,11,12,4,15,2 13,8,11,5,6,15,0,3,4,7,2,12,1,10,14,9,3 10,6,9,0,12,11,7,13,15,1,3,14,5,2,8,4,4 3,15,0,6,10,1,13,8,9,4,5,11,12,7,2,14
S-box5
1 2,12,4,1,7,10,11,6,8,5,3,15,13,0,14,9,2 14,11,2,12,4,7,13,1,5,0,15,10,3,9,8,6,3 4,2,1,11,10,13,7,8,15,9,12,5,6,3,0,14,4 11,8,12,7,1,14,2,13,6,15,0,9,10,4,5,3
S-box6
1 12,1,10,15,9,2,6,8,0,13,3,4,14,7,5,11,2 10,15,4,2,7,12,9,5,6,1,13,14,0,11,3,8,3 9,14,15,5,2,8,12,3,7,0,4,10,1,13,11,6,4 4,3,2,12,9,5,15,10,11,14,1,7,6,0,8,13
S-box7
1 4,11,2,14,15,0,8,13,3,12,9,7,5,10,6,1,2 13,0,11,7,4,9,1,10,14,3,5,12,2,15,8,6,3 1,4,11,13,12,3,7,14,10,15,6,8,0,5,9,2,4 6,11,13,8,1,4,10,7,9,5,0,15,14,2,3,12
S-box8
1 13,2,8,4,6,15,11,1,10,9,3,14,5,0,12,7,2 1,15,13,8,10,3,7,4,12,5,6,11,0,14,9,2,3 7,11,4,1,9,12,14,2,0,6,10,13,15,3,5,8,4 2,1,14,7,4,10,8,13,15,12,9,0,3,5,6,11
S-box的计算规则:
以S-box8为例,如果该盒输入为六位011100。取第一位和最后一位组成二进制数00,转化为十进制为0,对应该盒第1行。中间四位组成1110,十进制化为14,对应该盒第15列(考试的时候这个地方错了,,,1551)寻找该盒第1行第15列的元素,是12,转化为2进制是1100,这也就是该盒的输出。
在经过了S-box置换后,数据块还需一步处理,P-box
P-box很简单,类似于pc-1,就是简单的置换,32位的输入置换为32位的输出。置换表如下:
1 16,7,20,21,29,12,28,17,1,15,23,26,5,18,31,10,2 2,8,24,14,32,27,3,9,19,13,30,6,22,11,4,25
在经过了这些处理后,原来32位的R0变为了新的32位数据块,这个时候,使用这32位数据块和原来的L0进行异或,变为新的32位R1,这时候,原来的R0成为新的L1。R1再经过E-box扩展,和k2(第二个子密钥)异或,S-box替代,P-box置换的过程。再与L1进行异或,直到使用完所有的16个子密钥(也是16轮)。
明文经过了这16轮变换之后已经面目全非,这个时候把L和R组合成为64位经过最后的置换,即成为密文。最终置换如下:
1 40,8,48,16,56,24,64,32,39,7,47,15,55,23,63,31,2 38,6,46,14,54,22,62,30,37,5,45,13,53,21,61,29,3 36,4,44,12,52,20,60,28,35,3,43,11,51,19,59,27,4 34,2,42,10,50,18,58 26,33,1,41, 9,49,17,57,25
下面附上从别的老哥那抄来的介绍:
DES的特点:
优点:
效率高,算法简单,系统开销小(真的简单吗,,,,)
适合加密大量数据
明文长度和密文长度相等
缺点:
需要以安全方式进行秘钥交换
秘钥管理复杂
-
DES加密算法JAVA实现
2013-01-11 19:49:14通过java实现的DES加密算法,加深对加密机制的了解 -
DES+3DES加密算法java代码(+图解)
2013-09-29 12:57:36DES加密图解、DES的java实现代码、3DES的java实现代码 -
Java 3des加密算法ECB模式
2017-11-10 09:54:01Java 3des加密算法ECB模式,亲测完美通过。目前网上的大部分算法都通不过或者加进Base64之类的,还要不下载其它jar包。而代码使用时直接下载运行,无须配置和下载额外的jar包 ,只需换上自己的密钥和待加密的数据... -
DES加密算法的JAVA实现
2019-12-27 18:24:17运行环境:Windows + eclipse + JAVA ...DES算法把64位的明文输入块变为64位的密文输出块,它所使用的密钥也是64位(实际用到了56位,第8、16、24、32、40、48、56、64位是校验位, 使得每个密钥都有奇数个1) -
java加密算法之DES篇
2021-06-04 08:46:57加密 public static String encrypt(String datasource) { try{ DESKeySpec desKey = new DESKeySpec(PASSWORD.getBytes()); //创建一个密匙工厂,获取secretKey SecretKeyFactory keyFactory = ... -
常用MD5加密算法和3-DES加密算法java实现
2011-10-22 00:32:54常用MD5加密算法和3-DES加密算法java实现,在实际项目中我们会经常用到加密字符串,用md5算法是很多人的选择,其中包含源码,可直接使用。 -
DES加密解密Java工具
2018-07-18 21:20:50des对称加密,对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码),是一种对称加密算法。 -
DES加密算法 JAVA语言
2012-06-04 09:42:46JAVA语言编写的DES算法,自己做毕设用到的 -
DES加密算法java实现
2019-07-23 18:17:30由于计算机软件的非法复制,通信的泄密、数据安全受到威胁,解密及盗版问题日益严重,甚至引发国际争端,所以在信息安全技术中,加密技术占有不可替代的位置,因此对信息加密技术和加密手段的研究与开发,受到各国... -
python实现的DES加密算法和3DES加密算法实例
2020-12-23 21:32:31本文实例讲述了python实现的DES加密算法和3DES加密算法。分享给大家供大家参考。具体实现方法如下: ############################################################################# # Documentation # #########... -
java实现DES算法加密解密
2022-02-21 11:15:31} /** * DES加密字符串 * * @param password 加密密码,长度不能够小于8位 * @param data 待加密字符串 * @return 加密后内容 */ public static String encrypt(String password, String data) { if (password== ... -
DES算法Java实现
2018-01-17 09:45:05DES算法,可扩展成3DES算法,Java实现,Eclipse中可直接运行