DES加密算法的JAVA实现
- 格式:doc
- 大小:185.50 KB
- 文档页数:25
des加密算法java代码1、DES加密算法Java实现(1)导入所需要的包:import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;(2)定义加密算法:public class DesEncrypter {Cipher ecipher;Cipher dcipher;public DesEncrypter(String passPhrase) {try {// Create the keyDESKeySpec keySpec = newDESKeySpec(passPhrase.getBytes('UTF8'));SecretKeyFactory keyFactory =SecretKeyFactory.getInstance('DES');SecretKey key = keyFactory.generateSecret(keySpec); // Create the cipherecipher = Cipher.getInstance('DES');dcipher = Cipher.getInstance('DES');// Initialize the cipher for encryptionecipher.init(Cipher.ENCRYPT_MODE, key);// Initialize the same cipher for decryption dcipher.init(Cipher.DECRYPT_MODE, key);} catch (Exception e) {}}(3)定义加密函数:public String encrypt(String str) {try {// Encode the string into bytes using utf-8 byte[] utf8 = str.getBytes('UTF8');// Encryptbyte[] enc = ecipher.doFinal(utf8);// Encode bytes to base64 to get a stringreturn new sun.misc.BASE64Encoder().encode(enc);} catch (Exception e) {}return null;}(4)定义解密函数:// Decryptpublic String decrypt(String str) {try {// Decode base64 to get bytesbyte[] dec = newsun.misc.BASE64Decoder().decodeBuffer(str);// Decryptbyte[] utf8 = dcipher.doFinal(dec);// Decode using utf-8return new String(utf8, 'UTF8');} catch (Exception e) {}return null;}}(5)定义测试类,测试加密解之密是否正确:public class TestDes {public static void main(String[] args) {try {// Create encrypter/decrypter classDesEncrypter encrypter = new DesEncrypter('your key');// EncryptString encrypted = encrypter.encrypt('Don't tell anybody!');// DecryptString decrypted = encrypter.decrypt(encrypted);// Print out valuesSystem.out.println('Encrypted: ' + encrypted);System.out.println('Decrypted: ' + decrypted);} catch (Exception e) {}}}。
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加密,得到第二组密文C24)之后的数据以此类推,得到Cn5)按顺序连为即为加密结果。
解密是加密的逆过程,步骤如下:)首先将数据按照8个字节一组进行分组得到2)将第一组数据进行解密后与初始化向量I进行异或得到第一组明文D1(注意:一定是先解密再异或)3)将第二组数据C2进行解密后与第一组密文数据进行异或得到第二组数据D24)之后依此类推,得到Dn5)按顺序连为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 modeCipher 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 modeCipher 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算法,解密出错。
Java实现DES加密解密DES(Data Encryption Standard)是⼀种对称加密算法,所谓对称加密就是加密和解密都是使⽤同⼀个密钥加密原理:DES 使⽤⼀个 56 位的密钥以及附加的 8 位奇偶校验位,产⽣最⼤ 64 位的分组⼤⼩。
这是⼀个迭代的分组密码,使⽤称为 Feistel 的技术,其中将加密的⽂本块分成两半。
使⽤⼦密钥对其中⼀半应⽤循环功能,然后将输出与另⼀半进⾏"异或"运算;接着交换这两半,这⼀过程会继续下去,但最后⼀个循环不交换。
DES 使⽤ 16 个循环,使⽤异或,置换,代换,移位操作四种基本运算。
不过,DES已可破解,所以针对保密级别特别⾼的数据推荐使⽤⾮对称加密算法。
下⾯介绍基于Java实现的DES加解密⽅法,该⽅法同样适⽤于Android平台,使⽤的是JDK1.8。
public class DESUtil {/*** 偏移变量,固定占8位字节*/private final static String IV_PARAMETER = "12345678";/*** 密钥算法*/private static final String ALGORITHM = "DES";/*** 加密/解密算法-⼯作模式-填充模式*/private static final String CIPHER_ALGORITHM = "DES/CBC/PKCS5Padding";/*** 默认编码*/private static final String CHARSET = "utf-8";/*** ⽣成key** @param password* @return* @throws Exception*/private static Key generateKey(String password) throws Exception {DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM);return keyFactory.generateSecret(dks);}/*** DES加密字符串** @param password 加密密码,长度不能够⼩于8位* @param data 待加密字符串* @return 加密后内容*/public static String encrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能⼩于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);byte[] bytes = cipher.doFinal(data.getBytes(CHARSET));//JDK1.8及以上可直接使⽤Base64,JDK1.7及以下可以使⽤BASE64Encoder//Android平台可以使⽤android.util.Base64return new String(Base64.getEncoder().encode(bytes));} catch (Exception e) {e.printStackTrace();return data;}}/*** DES解密字符串** @param password 解密密码,长度不能够⼩于8位* @param data 待解密字符串* @return 解密后内容*/public static String decrypt(String password, String data) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能⼩于8位");}if (data == null)return null;try {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);return new String(cipher.doFinal(Base64.getDecoder().decode(data.getBytes(CHARSET))), CHARSET); } catch (Exception e) {e.printStackTrace();return data;}}/*** DES加密⽂件** @param srcFile 待加密的⽂件* @param destFile 加密后存放的⽂件路径* @return 加密后的⽂件路径*/public static String encryptFile(String password, String srcFile, String destFile) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能⼩于8位");}try {IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, generateKey(key), iv);InputStream is = new FileInputStream(srcFile);OutputStream out = new FileOutputStream(destFile);CipherInputStream cis = new CipherInputStream(is, cipher);byte[] buffer = new byte[1024];int r;while ((r = cis.read(buffer)) > 0) {out.write(buffer, 0, r);}cis.close();is.close();out.close();return destFile;} catch (Exception ex) {ex.printStackTrace();}return null;}/*** DES解密⽂件** @param srcFile 已加密的⽂件* @param destFile 解密后存放的⽂件路径* @return 解密后的⽂件路径*/public static String decryptFile(String password, String srcFile, String destFile) {if (password== null || password.length() < 8) {throw new RuntimeException("加密失败,key不能⼩于8位");}try {File file = new File(destFile);if (!file.exists()) {file.getParentFile().mkdirs();file.createNewFile();}IvParameterSpec iv = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET));Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, generateKey(key), iv);InputStream is = new FileInputStream(srcFile);OutputStream out = new FileOutputStream(destFile);CipherOutputStream cos = new CipherOutputStream(out, cipher);byte[] buffer = new byte[1024];int r;while ((r = is.read(buffer)) >= 0) {cos.write(buffer, 0, r);}cos.close();is.close();out.close();return destFile;} catch (Exception ex) { ex.printStackTrace(); }return null;}}。
目录摘要 (3)一、目的与意义 (4)二、DES概述 (5)三、DES加解密算法原理 (7)1.加密 (6)2.子密钥生成 (11)3.解密 (13)四、加解密算法的实现 (14)1.软件版本 (14)2.平台 (14)3.源代码 (14)4.运行结果 (24)五、总结 (25)【摘要】1973年5月15 日,美国国家标准局(现在的美国国家标准就是研究所,即NIST)在联邦记录中公开征集密码体制,这一举措最终导致了数据加密标准(DES)的出现,它曾经成为世界上最广泛使用的密码体制。
DES由IBM开发,它是早期被称为Lucifer体制的改进。
DES在1975年3月17日首次在联邦记录中公布,在经过大量的公开讨论后,1977年2月15日DES被采纳为“非密级”应用的一个标准。
最初预期DES作为标准只能使用10~15年;然而,事实证明DES要长寿得多。
被采纳后,大约每隔5年就被评审一次。
DES的最后一次评审是在1999年1月。
本文阐述了DES发展现状及对网络安全的重要意义,并在此基础上对DES算法原理进行详细的介绍和分析。
通过应用DES算法加解密的具体实现,进一步加深对DES算法的理解,论证了DES算法具有加密快速且强壮的优点,适合对含有大量信息的文件进行加密,同时分析了DES算法密钥过短(56位)所带来的安全隐患。
【关键词】DES 加密解密明文密文一、目的与意义随着计算机和通信网络的广泛应用,信息的安全性已经受到人们的普遍重视。
信息安全已不仅仅局限于政治,军事以及外交领域,而且现在也与人们的日常生活息息相关。
现在,密码学理论和技术已得到了迅速的发展,它是信息科学和技术中的一个重要研究领域。
在近代密码学上值得一提的大事有两件:一是1977年美国国家标准局正式公布实施了美国的数据加密标准(DES),公开它的加密算法,并批准用于非机密单位及商业上的保密通信。
密码学的神秘面纱从此被揭开。
二是Diffie和Hellman联合写的一篇文章“密码学的新方向”,提出了适应网络上保密通信的公钥密码思想,拉开了公钥密码研究的序幕。
成都信息工程学院课程设计报告DES加密解密算法的实现(Java)课程名称:应用密码算法程序设计学生姓名:李文浩学生学号: 2007122054专业班级:信安072班任课教师:万武南2009年 11 月 11 日附件:课程设计成绩评价表目录1.引言 (1)1.1 背景 (1)1.2 目的 (1)1.3 本设计的主要任务 (1)2.系统设计 (2)2.1系统主要目标 (2)2.1.1主要软件需求(运行环境) (2)2.2 系统结构 (2)2.2.2 软件操作流程 (2)2.2.3功能模块 (3)3 系统功能程序设计 (3)3.1循环移位 (3)3.2获取RoundKey (4)3.3 IP置换,逆置换,E扩展,置换P (5)3.4 Fnew函数(F函数) (5)3.5异或 (7)3.6 S盒代替 (7)3.7十六进制转二进制 (7)3.8二进制转十六进制 (8)3.9加密 (9)3.10解密 (9)3.11程序界面预览 (10)4. 测试报告 (11)5.结论 (14)参考文献 (14)1.引言1.1 背景数据加密标准(Data Encryption Standard,,DES)曾被美国国家标准局(NBS,现为国家标准与技术研究所NIST)确定为联邦信息处理标准(FIPS PUB 46),得到过广泛使用,特别是在金融领域,曾是对称密码体制事实上的世界标准。
目前在国内,随着三金工程尤其是金卡工程的启动,DES算法在POS,A TM,智能卡,加油站,高速公路收费站等领域被广泛使用,以此来实现关键数据加密,如信用卡持卡人的PIN的加密传输,IC卡与POS间的双向认证、金融交易数据包的MAC校验等,均用到DES算法。
DES起源于1973年美国国家标准局NBS征求国家密码标准方案。
IBM就提交了其在20世纪60年代末设立的一个计算机密码编码学方面的研究项目的结果,这个项目在1971年结束时研制出了一种称为Lucifer算法。
DES加密算法代码java实现DES加密1.准备算法所需要的密钥在Java中,DES加密算法需要一个8字节长的密钥,这里使用原始的8字节长的密钥来实现DES加密算法,同时,还有一种是“密钥扩展”,可以将8字节长的密钥扩展为16字节长,只需要多添加8个字节,后面8个字节可以跟前面8字节保持一致即可,即扩展后的密钥和原始密钥共享后八个字节即可。
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};下面介绍如何用Java来实现原始的8字节长的密钥:// 生成keyKeyGenerator keyGenerator = KeyGenerator.getInstance("DES");keyGenerator.init(new SecureRandom(keyBytes));SecretKey key = keyGenerator.generateKey(;2. 设置加密模式(Cipher Block Chaining Mode,简称CBC模式)在Java中,DES加密算法可以支持三种不同的加密模式:ECB,CBC,CFB。
其中ECB模式为最原始的模式,它不需要任何附加的参数,而CBC模式需要一个8字节的初始向量(Initial Vector,IV)参数,CFB模式需要一个1字节或8字节的变量参数,它们用来增加加密的强度。
这里,我们使用CBC模式,它是最常用的DES加密模式,下面是设置CBC模式所需要的参数:// 创建Cipher对象,指定其支持的DES算法Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");// 用密匙初始化Cipher对象IvParameterSpec param = new IvParameterSpec(iv);cipher.init(Cipher.ENCRYPT_MODE, key,param);3.加密。
DES加密算法的JAVA实现DES是一种对称加密算法,它将明文划分为64位的数据块,并对每个数据块进行一系列的转换和替代操作,最终生成密文。
在Java中,可以使用javax.crypto包提供的API来实现DES加密算法。
首先,需要导入javax.crypto包和java.security包。
```javaimport javax.crypto.Cipher;import javax.crypto.spec.SecretKeySpec;import java.security.Key;``````javapublic class DESUtilprivate static final String ALGORITHM = "DES";public static Key generateKey(byte[] keyData) throws Exceptionreturn new SecretKeySpec(keyData, ALGORITHM);}```接下来,我们需要编写加密和解密的方法。
```javapublic class DESUtil//...public static byte[] encrypt(byte[] data, Key key) throws ExceptionCipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, key);return cipher.doFinal(data);}public static byte[] decrypt(byte[] encryptedData, Key key) throws ExceptionCipher cipher = Cipher.getInstance(ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, key);return cipher.doFinal(encryptedData);}```在上述代码中,encrypt方法用于将明文数据加密成密文,decrypt 方法用于将密文数据解密成明文。
信息安全概论JAVA实现DES加密算法学号:********* 姓名:高玉林Java实现DES加密算法目录DES算法概述 (3)DES的加密过程 (4)DES算法细节 (4)DES的解密过程 (8)源代码与结果(使用Java实现) (9)源代码 (9)运行结果截图 (21)默认密钥(“这不是密码”) (21)用户自定义密钥(以“nuaasillydes”为例) (21)总结 (22)DES算法概述DES全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。
它是ANSI的数据加密算法和ISO的DEA-1,成为一个世界范围内的标准已经近30年。
尽管DES带有过去时代的特征,但是它很好的抵抗住了多年的密码分析,除可能的最强有力的敌手外,对其他的攻击仍是安全的。
DES是一个分组加密算法,它以64位为一组对数据进行加密。
64位一组的明文从算法的一端输入,64位的密文从另一端输出。
DES是一个对称算法:加密与解密用的是同一算法(除密钥编排不同以外)。
密钥的长度为56位,通常表示为64位的数,但是每个第八位都用作奇偶校验,可以忽略。
密钥可以是任意的56位的数,且可在任意的时候改变。
DES的整体结构为:DES的加密过程DES的加密过程如下。
(1)64位的密钥经子密钥产生算法产生出16个子密钥K1,K2,……,K16,分别供第1次,第2次,……,第16次加密迭代使用。
(2)64位明文首先经过初始置换IP(Initial Permutation),将数据打乱重新排列并分成左右两半。
左边32位构成L,右边32为构成R。
(3)由加密函数f实现子密钥k1对R0的加密,结果得到32位的数据组f(R0,K1)。
F(R0,K1)再与L0异或,又得到一个32位的数据组L0➕f(R0,K1)。
以L0➕f(R0,K1)作为第2次加密迭代的R1,以R0作为第2次加密迭代的L1。
至此,第1次加密迭代结束。
DES加密算法详细原理以及Java代码实现本周的密码学实验要求使⽤任意编程语⾔来实现des加密算法,于是我在查阅了相关资料后有了以下成果。
⾸先,DES算法作为经典的分块密码(block cipher),其主要的实现过程由两部分组成,分别是密钥的⽣成以及明⽂的处理。
加密的⼤致流程如图所⽰作为分块密码,密钥的输⼊以及明⽂的输⼊均为64位2进制数。
下⾯⾸先来说密钥的⽣成过程。
密钥处理部分如图所⽰ 密钥的输⼊为64位,例如00010011 00110100 01010111 01111001 10011011 10111100 11011111 11110001,然后经过pc-1盒置换,会去除每⼀个8的倍数位(奇偶校验位)并打乱次序,将密钥变为56位。
pc-1的置换表如下(框中的数字代表的是原密钥的位置,⽽不是数据)157,49,41,33,25,17,9,1,258,50,42,34,26,18,10,2,359,51,43,35,27,19,11,3,460,52,44,36,63,55,47,39,531,23,15,7,62,54,46,38,630,22,14,6,61,53,45,37,729,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)。
114,17,11,24,1,5,23,28,15,6,21,10,323,19,12,4,26,8,416,7,27,20,13,2,541,52,31,37,47,55,630,40,51,45,33,48,744,49,39,56,34,53,846,42,50,36,29,32 经过了pc-2盒的置换后,原本56位的密钥会变为48位。
周胜安(200620109286) 计算机科学与工程研一(2)班S-DES加密算法的JAVA实现一、实验要求(1)简述S-DES的加密算法的主要思想(2)实现的主要步骤,及各个步骤的主要思想及示意图(3)给出程序的分析,运行结果和程序的效率分析(4)通过编程实现S-DES加密算法,了解DES加密的原理,也加深对现代对称密码的理解。
二、算法思想•加密算法的数学表示:密文=IP-1fk2(SW(fk1(IP(明文)))))其中K1=P8(移位(P10(密钥K)))K2=P8(移位(移位(P10(密钥K))))• 解密算法的数学表示:明文=IP-1(fk1(SW(fk2(IP(密文)))))S-DES 加密方法示意图:S-DES算法涉及加密、密钥产生、解密三个部分。
流程图(每个函数的算法见源代码)三、算法流程框图、各模块说明实验是用JAVA实现的(1)密钥的产生密钥产生的示意图:密钥的产生算法涉及五个函数定义(1)初始置换P10 其中P10的定义为:P10(k1,k2,…,k10)=(k3,k5,k2,k7,k4,k10,k1,k9,k8,k6)(2)LS-1操作:对密钥的左右两组循环左移一位(密钥分成5位一组,共2组)(3)P8置换产生Key1。
其中P8的定义为:P8(k1,k2,…,k10)=(k6,k3,k7,k4,k8,k5,k10,k9)(4)LS-2操作: :对密钥的左右两组循环左移两位.(5) P8置换产生Key2(2) S-DES 的加密过程示意图:加密算法涉及五个函数:(1)初始置换IP(initial permutation)。
其中P8的定义为:IP(k1,k2,…,k8)=(k2,k6,k3,k1,k4,k8,k5,k7)(2)复合函数fk,它是由密钥K确定的,具有置换和代替的运算。
函数fk,是加密方案中的最重要部分,它可表示为:fk(L,R)=(L F(R,SK),R)其中L,R为8位输入, 左右各为4位, F为从4位集到4位集的一个映射, 并不要求是1-1的。
以下为DES加密算法的实现(附控制台输出调试代码)/*** Created on __DATE__, __TIME__*/package deswindow;import java.util.Scanner;/**** @author __USER__*/public class Window extends javax.swing.JFrame {/** Creates new form Window */public Window() {initComponents();}/** This method is called from within the constructor to* initialize the form.* WARNING: Do NOT modify this code. The content of this method is* always regenerated by the Form Editor.*///GEN-BEGIN:initComponents// <editor-fold defaultstate="collapsed" desc="Generated Code">private void initComponents() {button1 = new java.awt.Button();textField1 = new java.awt.TextField();textField2 = new java.awt.TextField();内容= new bel();密钥= new bel();textArea1 = new java.awt.TextArea();button2 = new java.awt.Button();setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);button1.setLabel("加密");er(new java.awt.event.ActionListener() {public void actionPerformed(java.awt.event.ActionEvent evt) {button1ActionPerformed(evt);}});textField1.setText("请输入明文或者密文");textField1.addActionListener(new java.awt.event.ActionListener() {public void actionPerformed(java.awt.event.ActionEvent evt) {textField1ActionPerformed(evt);}});textField2.setText("请输入密钥");textField2.addActionListener(new java.awt.event.ActionListener() {t.ActionEvent evt) {textField2ActionPerformed(evt);}});内容.setText("内容");密钥.setText("密钥");button2.setLabel("解密");button2.addActionListener(new java.awt.event.ActionListener() {vent evt) {button2ActionPerformed(evt);}});javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());getContentPane().setLayout(layout);layout.setHorizontalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addGap(127, 127, 127).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(textArea1,javax.swing.GroupLayout.Alignment.TRAILING,javax.swing.GroupLayout.DEFAULT_SIZE,124,Short.MAX_VALUE).addGroup( layout.createSequentialGroup().addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(javax.swing.GroupLayout.Alignment.TRAILING,layout.createSequentialGroup().addPreferredGap(ponentPlacement.RELATED).addComponent(内容,javax.swing.GroupLayout.PREFERRED_SIZE,38,javax.swing.GroupLayout.PREFERRED_SIZE)) .addComponent(密钥,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)).addGap(2,2,2).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(textField1,javax.swing.GroupLayout.DEFAULT_SIZE,84,Short.MAX_V ALUE).addComponent(textField2,javax.swing.GroupLayout.DEFAULT_SIZE,84,Short.MAX_V ALUE)))).addGroup(layout.createSequentialGroup().addComponent(button1, javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE).addPreferredGap(ponentPlacement.RELATED).addComponent(button2, javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE))).addGap(149, 149, 149)));layout.setVerticalGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addGroup(layout.createSequentialGroup().addGap(29, 29, 29).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addComponent(textField1,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(内容,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)).addPreferredGap(t.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING).addComponent(密钥,javax.swing.GroupLayout.PREFERRED_SIZE,out.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(textField2,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)).addPreferredGap(ponentPlacement.RELATED).addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING).addComponent(button2,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE).addComponent(button1,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)).addPreferredGap(ponentPlacement.RELATED).addComponent(textArea1,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE).addContainerGap(91, Short.MAX_V ALUE)));pack();}// </editor-fold>//GEN-END:initComponentsprivate void button2ActionPerformed(java.awt.event.ActionEvent evt) {// 解密得到两个输入框的输入值textArea1.setText("");// textArea1.append("欢迎使用64位DES加密解密演示程序。
一、实验目的用java编程实现DES加解密算法,以便深入理解DES加解密算法原理。
二、实验条件1、熟悉JA V A开发环境,能熟练运用JA V A进行程序编写;2、掌握DES加解密算法知识,了解其算法原理;3、安装了JA V A环境的计算机。
三、实验原理1、DES加解密过程:1)、初始置换:对于给定的明文分组x,通过初始置换表IP对x进行置换,得到一个64位的输出串x0,即将输入的第58位换到第一位,第50位换到第2位,...,依此类推,最后一位是原来的第7位。
对于所得到64位的输出串x0,记x0 = IP(x) = L0 R0,其中L0为x0的前32位,R0为x0的后32位。
2)、迭代变换:按照规则迭代。
规则为:Li=Ri-1Ri=Li⊕f(Ri-1, Ki) (i=1,2,3, (16)经过第1步变换已经得到L0和R0的值,其中符号⊕表示数学运算“异或”,f表示一种置换,由s盒置换构成,Ki是一些由密钥编排函数产生的比特块。
迭代变换利用16轮循环,每轮循环使用子密钥对Li 和Ri进行分别处理,对输出结果进行异或运算和交换操作,以实现数据和密钥的结合。
3)、逆置换:类似的,经过16轮迭代后所得到的串R16 、L16应用初始置换的逆置换IP-1,获得密文y,即y = IP-1(R16 , L16)。
2、密码函数f函数f的输入是一个32比特串(当前状态的右半部)和子密钥。
密钥编排方案(k1,k2,…,k32)由16个48比特的子密钥组成,这些子密钥由56比特的种子密钥k 导出。
每个ki 都是由置换选择而来,子密钥的产生过程后面详述。
它主要包含了一个应用S 盒的替代以及其后跟随的一个固定置换P 。
密码函数f 是整个加密的关键部分,它包含了如下四个功能:扩展函数E 、S 盒运算、模2加法、置换函数。
其中,E 位选择表如下:Ki 是由密钥产生的48位比特串,具体的算法是:将E 的选位结果与 ki 作异或操作,得到一个48位输出。
数据结构算法:java实现DES加密算法java实现DES加密算法为了实现一对密钥对整个项目所有加密解密文件都适用的方法,考试,大提示采用先生成一对密钥.保存到xml文件中,以后获得私匙和公钥只需要从xml文件中取得就可以了./*** 把成生的一对密钥保存到DesKey.xml文件中*/public static void saveDesKey(){try {SecureRandom sr = new SecureRandom();//为我们选择的DES算法生成一个KeyGenerator对象KeyGenerator kg = KeyGenerator.getInstance (\"DES\" );kg.init (sr);FileOutputStream fos = new FileOutputStream(\"C:/DesKey.xml\");ObjectOutputStream oos = new ObjectOutputStream(fos);//生成密钥Key key = kg.generateKey();oos.writeObject(key);oos.close();} catch (Exception e) {e.printStackTrace();}}获取密钥方法如下:/*** 获得DES加密的密钥。
在交易处理的过程中应该定时更* 换密钥。
需要JCE的支持,如果jdk版本低于1.4,则需要* 安装jce-1_2_2才能正常使用。
* @return Key 返回对称密钥*/public static Key getKey() {Key kp = null;try {String fileName = \"conf/DesKey.xml\";InputStream is = DesUtil.class.getClassLoader().getResourceAsStream(fileName);ObjectInputStream oos = new ObjectInputStream(is);kp = (Key) oos.readObject();oos.close();} catch (Exception e) {e.printStackTrace();}return kp;}文件采用DES算法加密文件/*** 文件file进行加密并保存目标文件destFile中* @param file* 要加密的文件如c:/test/srcFile.txt* @param destFile* 加密后存放的文件名如c:/加密后文件.txt*/public static void encrypt(String file, String destFile) throws Exception { Cipher cipher = Cipher.getInstance(\"DES\");cipher.init(Cipher.ENCRYPT_MODE, getKey());InputStream is = new FileInputStream(file);OutputStream out = new FileOutputStream(dest); CipherInputStream cis = new CipherInputStream(is, cipher);byte[] buffer = new byte[1024];int r;while ((r = cis.read(buffer)) > 0) {out.write(buffer, 0, r);}cis.close();is.close();out.close();}文件采用DES算法解密文件/*** 文件file进行加密并保存目标文件destFile中* @param file* 已加密的文件如c:/加密后文件.txt* @param destFile* 解密后存放的文件名如c:/ test/解密后文件.txt*/public static void decrypt(String file, String dest) throws Exception { Cipher cipher = Cipher.getInstance(\"DES\");cipher.init(Cipher.DECRYPT_MODE, getKey());InputStream is = new FileInputStream(file);OutputStream out = new FileOutputStream(dest); CipherOutputStream cos = new CipherOutputStream(out, cipher);byte[] buffer = new byte[1024];int r;while ((r = is.read(buffer)) >= 0) {cos.write(buffer, 0, r);}cos.close();out.close();is.close(); }。
DES详解(Java实现)DES 数据加密标准(Data Encryption Standard),简称DES,是由IBM公司提交,美国政府于1977年1⽉5⽇颁布的⼀种加密算法。
DES的设计⽬标是,⽤于加密保护静态存储和传输信道中的数据,安全使⽤10~15年。
DES综合运⽤了置换、代替、代数等多种密码技术。
它设计精巧、实现容易、使⽤⽅便,堪称是适应计算机环境的近代分组密码的⼀个典范。
DES的设计充分体现了Shannon所阐述的设计密码的思想,标志着密码的设计与分析达到了新的⽔平。
DES是⼀种分组密码。
明⽂、密⽂和密钥的分组长度都是64位。
DES是⾯向⼆进制的密码算法。
因⽽能够加解密任何形式的计算机数据。
DES是对合运算,因⽽加密和解密共⽤同⼀算法,从⽽使⼯程实现的⼯作量减半。
DES的密码结构属于Feistel结构。
Feistel结构 Feistel结构是IBM的密码专家Horst Feistel最早提出的。
由于它是对称的密码结构,所以对信息加密和解密的过程就极为相似,甚⾄完全⼀样。
这就使得在实施的过程中,对编码量和线路传输的要求就减少了⼏乎⼀半。
加密结构 L i = R i-1 R i = L i-1 ⊕ f ( R i-1 , k i )解密结构 L i-1 = R i ⊕ f ( L i , k i ) R i-1 = L i影响因素 影响Feistel结构的因素有以下5个: 1.块的⼤⼩:⼤的块会提⾼加密的安全性,但是会降低加密、解密的速度; 2.密钥的⼤⼩:⼤的密钥也会提⾼加密的安全性,但是也会降低加密、解密的速度; 3.轮次数:每多进⾏⼀轮循环,安全性就会有所提⾼; 4.⼦密钥的⽣成算法:⽣成算法越复杂,则会使得密⽂被破译的难度增强,即信息会越安全; 5.轮函数的复杂度:轮函数越复杂,则安全性会越⾼。
DES算法细节⼦密钥的产⽣ 64位密钥经过置换选择1、循环左移、置换选择2等变换,产⽣出16个48位长的⼦密钥。
实验二:DES的编程实现一、实验目的在本实验中,用VC/ C/C++/Java实现DES的加解密算法。
完成实验后将能够深入理解DES加解密算法及其在VC/ C/C++/Java中的实现过程。
二、实验条件熟悉VC/ C/C++/Java开发环境和有关DES算法的有关知识;一台安装有VC/ C/C++/Java 的计算机。
三、实验要求本实验要求:输入十六位十六进制明文(占64Bit)和十六位十六进制密钥(占64Bit),输出十六位十六进制密文和六十四位二进制密文。
四、实验步骤对数据进行加密传输能有效地保证数据的机密性,DES是一个保证数据机密性的经典算法,本实验拟在VC/ C/C++/Java环境中实现DES算法。
以下以VC为例:主要内容:在VC中建立三个文件:控制台应用程序的入口点:testMain.cpp,DES2加密类cpp文件zlDES2.cpp,DES2加密类头文件zlDES2.h。
操作步骤:(1)进入VC环境;(2)在VC环境中,执行“文件| 新建”命令,在“新建”对话框中(如图1)选择“文件”页,在其左侧的列表框中选择“Win32 Console Application”,在右侧的“文件名”文本框中输入新文件名“DES”,在“位置”文本框中选择项目的存储路径(比如选择“e:\des”)。
然后单击“确定”按钮。
图1 “New(新建)”对话框(3)“Win32 Console Application-步骤1共1步”对话框中,选择“一个空工程”单选按钮,单击“完成”按钮,再单击“确定”按钮。
图2 “Win32 Console Application-步骤1共1步”对话框(4)在VC环境中,在其左侧的工程工作区窗口下端中选择标签“FileView”,单击“DES files”前面的“+”号展开。
图3 标签“FileView”(5)鼠标右击“Source Files”,选择“添加文件到目录”,将testMain.cpp和zlDES.cpp 添加进“Source Files”。
JAVA上DES加密算法的实现用例First we should implement Oracle’s DES arithmetic using Java. Now Java provide the DES arithmetic in jce.jar. So we only work is provide the transformation.Please refer JavaDoc and Oracle forumThe function of the code that listed is same as oracle’s dbms_obfuscation_toolkit DES arithmeticpackage util;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.IvParameterSpec;import ng.ArrayUtils;public class Encryption {private Cipher en;private Cipher de;public byte[] encrypt(String s) {try {byte[] data = s.getBytes("SJIS");if (data.length % 8 != 0) {int length = 8 - data.length % 8;byte[] spaces = new byte[length];for (int i = 0; i < spaces.length; i++) {spaces[i] = 0x20;}data = ArrayUtils.addAll(data, spaces);}return en.doFinal(data);} catch (Exception e) {throw new RuntimeException(e);}}public String decrypt(byte[] b) {try {byte[] data = de.doFinal(b);return new String(data, "SJIS").trim();} catch (Exception e) {throw new RuntimeException(e);}}private Encryption() {try {DESKeySpec deskey = new DESKeySpec("12345678".getBytes());SecretKeyFactory skf = SecretKeyFactory.getInstance("DES");SecretKey key = skf.generateSecret(deskey);IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 });en = Cipher.getInstance("DES/CBC/NoPadding");en.init(Cipher.ENCRYPT_MODE, key, iv);de = Cipher.getInstance("DES/CBC/NoPadding");de.init(Cipher.DECRYPT_MODE, key, iv);} catch (Exception e) {throw new RuntimeException(e);}}private static Encryption instance = new Encryption();public static Encryption getInstance() {return instance;}}Ok. I will create a column that will mapped to Hibernate. The type of the column should be RAW!VARCHAR2 is not a good choice, actually VARCHAR2 does not work with encrypted column , because can not get the correct encrypted data from VARCHAR2 type.CREATE TABLE ZENCRYPT(ID VARCHAR2(32CHAR)NOT NULL,ENCRYPT RAW(32))Then we will define a Hibernate UseType, this make encrypt and decrypt more transparent.package usertype;import java.io.Serializable;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Types;import org.hibernate.HibernateException;import erType;import util.Encryption;public class EncryptType implements UserType {public Object assemble(Serializable cached, Object owner) throws HibernateException {return null;}public Object deepCopy(Object value) throws HibernateException {if (value == null) {return null;} else {return new String((String) value);}}public Serializable disassemble(Object value) throws HibernateException {return null;}public boolean equals(Object x, Object y) throws HibernateException {return (x == y) || (x != null && y != null && (x.equals(y)));}public int hashCode(Object x) throws HibernateException { return x.hashCode();}public boolean isMutable() {return false;}public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException { //Get bin data from database then decrypt to Stringbyte[] data = rs.getBytes(names[0]);return Encryption.getInstance().decrypt(data);}public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {if (value == null) {return;}//Encrypt String to bin databyte data[] = Encryption.getInstance().encrypt(value.toString());st.setBytes(index, data);}public Object replace(Object original, Object target, Object owner) throws HibernateException {return null;}public Class returnedClass() {return ng.String.class;}public int[] sqlTypes() {return new int[] { Types.BINARY };}}Mapping file<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="entity.ZEncrypt" table="ZENCRYPT"><id name="ids" type="string"><column name="ID" /><generator class="assigned" /></id><property name="encrypt" type="usertype.EncryptType"> <column name="ENCRYPT" /></property></class></hibernate-mapping>。
java实现DES加密解密算法DES算法的⼊⼝参数有三个:Key、Data、Mode。
其中Key为8个字节共64位,是DES算法的⼯作密钥;Data也为8个字节64位,是要被加密或被解密的数据;Mode为DES的⼯作⽅式,有两种:加密或解密。
DES算法是这样⼯作的:如Mode为加密,则⽤Key 去把数据Data进⾏加密,⽣成Data的密码形式(64位)作为DES的输出结果;如 Mode为解密,则⽤Key去把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。
在通信⽹络的两端,双⽅约定⼀致的Key,在通信的源点⽤Key对核⼼数据进⾏DES加密,然后以密码形式在公共通信⽹(如电话⽹)中传输到通信⽹络的终点,数据到达⽬的地后,⽤同样的 Key对密码数据进⾏解密,便再现了明码形式的核⼼数据。
这样,便保证了核⼼数据(如PIN、MAC等)在公共通信⽹中传输的安全性和可靠性。
通过定期在通信⽹络的源端和⽬的端同时改⽤新的Key,便能更进⼀步提⾼数据的保密性,这正是现在⾦融交易⽹络的流⾏做法。
下⾯是具体代码:(切记切记字符串转字节或字节转字符串时⼀定要加上编码,否则可能出现乱码)1import java.io.IOException;2import java.security.SecureRandom;34import javax.crypto.Cipher;5import javax.crypto.SecretKey;6import javax.crypto.SecretKeyFactory;7import javax.crypto.spec.DESKeySpec;89import sun.misc.BASE64Decoder;10import sun.misc.BASE64Encoder;1112/**13 * DES加密解密算法14 *15 * @author lifq16 * @date 2015-3-17 上午10:12:1117*/18public class DesUtil {1920private final static String DES = "DES";21private final static String ENCODE = "GBK";22private final static String defaultKey = "test1234";2324public static void main(String[] args) throws Exception {25 String data = "测试ss";26// System.err.println(encrypt(data, key));27// System.err.println(decrypt(encrypt(data, key), key));28 System.out.println(encrypt(data));29 System.out.println(decrypt(encrypt(data)));3031 }3233/**34 * 使⽤默认key 加密35 *36 * @return String37 * @author lifq38 * @date 2015-3-17 下午02:46:4339*/41byte[] bt = encrypt(data.getBytes(ENCODE), defaultKey.getBytes(ENCODE));42 String strs = new BASE64Encoder().encode(bt);43return strs;44 }4546/**47 * 使⽤默认key 解密48 *49 * @return String50 * @author lifq51 * @date 2015-3-17 下午02:49:5252*/53public static String decrypt(String data) throws IOException, Exception {54if (data == null)55return null;56 BASE64Decoder decoder = new BASE64Decoder();57byte[] buf = decoder.decodeBuffer(data);58byte[] bt = decrypt(buf, defaultKey.getBytes(ENCODE));59return new String(bt, ENCODE);60 }6162/**63 * Description 根据键值进⾏加密64 *65 * @param data66 * @param key67 * 加密键byte数组68 * @return69 * @throws Exception70*/71public static String encrypt(String data, String key) throws Exception {72byte[] bt = encrypt(data.getBytes(ENCODE), defaultKey.getBytes(ENCODE));73 String strs = new BASE64Encoder().encode(bt);74return strs;75 }7677/**78 * Description 根据键值进⾏解密79 *80 * @param data81 * @param key82 * 加密键byte数组83 * @return84 * @throws IOException85 * @throws Exception86*/87public static String decrypt(String data, String key) throws IOException,88 Exception {89if (data == null)90return null;91 BASE64Decoder decoder = new BASE64Decoder();92byte[] buf = decoder.decodeBuffer(data);93byte[] bt = decrypt(buf, key.getBytes(ENCODE));94return new String(bt, ENCODE);95 }9698 * Description 根据键值进⾏加密99 *100 * @param data101 * @param key102 * 加密键byte数组103 * @return104 * @throws Exception105*/106private static byte[] encrypt(byte[] data, byte[] key) throws Exception { 107// ⽣成⼀个可信任的随机数源108 SecureRandom sr = new SecureRandom();109110// 从原始密钥数据创建DESKeySpec对象111 DESKeySpec dks = new DESKeySpec(key);112113// 创建⼀个密钥⼯⼚,然后⽤它把DESKeySpec转换成SecretKey对象114 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); 115 SecretKey securekey = keyFactory.generateSecret(dks);116117// Cipher对象实际完成加密操作118 Cipher cipher = Cipher.getInstance(DES);119120// ⽤密钥初始化Cipher对象121 cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);122123return cipher.doFinal(data);124 }125126/**127 * Description 根据键值进⾏解密128 *129 * @param data130 * @param key131 * 加密键byte数组132 * @return133 * @throws Exception134*/135private static byte[] decrypt(byte[] data, byte[] key) throws Exception { 136// ⽣成⼀个可信任的随机数源137 SecureRandom sr = new SecureRandom();138139// 从原始密钥数据创建DESKeySpec对象140 DESKeySpec dks = new DESKeySpec(key);141142// 创建⼀个密钥⼯⼚,然后⽤它把DESKeySpec转换成SecretKey对象143 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES); 144 SecretKey securekey = keyFactory.generateSecret(dks);145146// Cipher对象实际完成解密操作147 Cipher cipher = Cipher.getInstance(DES);148149// ⽤密钥初始化Cipher对象150 cipher.init(Cipher.DECRYPT_MODE, securekey, sr);151152return cipher.doFinal(data);153 }。
目录摘要 (3)一、目的与意义 (4)二、DES概述 (5)三、DES加解密算法原理 (7)1.加密 (6)2.子密钥生成 (11)3.解密 (13)四、加解密算法的实现 (14)1.软件版本 (14)2.平台 (14)3.源代码 (14)4.运行结果 (24)五、总结 (25)【摘要】1973年5月15 日,美国国家标准局(现在的美国国家标准就是研究所,即NIST)在联邦记录中公开征集密码体制,这一举措最终导致了数据加密标准(DES)的出现,它曾经成为世界上最广泛使用的密码体制。
DES由IBM开发,它是早期被称为Lucifer体制的改进。
DES在1975年3月17日首次在联邦记录中公布,在经过大量的公开讨论后,1977年2月15日DES被采纳为“非密级”应用的一个标准。
最初预期DES作为标准只能使用10~15年;然而,事实证明DES要长寿得多。
被采纳后,大约每隔5年就被评审一次。
DES的最后一次评审是在1999年1月。
本文阐述了DES发展现状及对网络安全的重要意义,并在此基础上对DES算法原理进行详细的介绍和分析。
通过应用DES算法加解密的具体实现,进一步加深对DES算法的理解,论证了DES算法具有加密快速且强壮的优点,适合对含有大量信息的文件进行加密,同时分析了DES算法密钥过短(56位)所带来的安全隐患。
【关键词】DES 加密解密明文密文一、目的与意义随着计算机和通信网络的广泛应用,信息的安全性已经受到人们的普遍重视。
信息安全已不仅仅局限于政治,军事以及外交领域,而且现在也与人们的日常生活息息相关。
现在,密码学理论和技术已得到了迅速的发展,它是信息科学和技术中的一个重要研究领域。
在近代密码学上值得一提的大事有两件:一是1977年美国国家标准局正式公布实施了美国的数据加密标准(DES),公开它的加密算法,并批准用于非机密单位及商业上的保密通信。
密码学的神秘面纱从此被揭开。
二是Diffie和Hellman联合写的一篇文章“密码学的新方向”,提出了适应网络上保密通信的公钥密码思想,拉开了公钥密码研究的序幕。
DES(Data Encryption Standard)是IBM公司于上世纪1977年提出的一种数据加密算法。
在过去近三十年的应用中,还无法将这种加密算法完全、彻底地破解掉。
而且这种算法的加解密过程非常快,至今仍被广泛应用,被公认为安全的。
虽然近年来由于硬件技术的飞速发展,破解DES已经不是一件难事,但学者们似乎不甘心让这样一个优秀的加密算法从此废弃不用,于是在DES的基础上有开发了双重DES(DoubleDES,DDES)和三重DES(Triple DES,TDES)。
在国内,随着三金工程尤其是金卡工程的启动,DES 算法在POS、ATM、磁卡及智能卡(IC 卡)、加油站、高速公路收费站等领域被广泛应用,以此来实现关键数据的保密,如信用卡持卡人的PIN 码加密传输,IC 卡与POS 间的双向认证、金融交易数据包的MAC 校验等,均用到DES 算法。
DES加密体制是ISO颁布的数据加密标准。
因此研究DES还是有非常重要的意义。
二、DES概述DES的前身是IBM的Lucifer算法,后经美国联邦采用这个算法后更名为数据加密标准。
DES是一种块加密算法,每块长64比特。
DES的密钥长度也是64比特,但由于其中的8,16,24,32,48,56,64为作为奇偶校验位,所以实际的密钥只有56比特。
DES利用了香农提出的混淆和扩散的概念。
DES共有16论,每一轮都进行混淆和扩散。
DES主要有三个步骤:(1)利用初始置换函数IP对64比特明文块进行初始置换。
将初始置换的输出分成联邦,分别表示为左明文L0和右明文R0。
(2)进行16次迭代,迭代规则如下:L i=R i,R i=L i-1⊕f(R i-1,K i)。
其中L i和R i分别表示第i轮的左半部和右半部。
f()是运算函数,K i是长为48位的子密钥。
子密钥K1,K2,……,K16是根据56比特的密钥K计算而来的。
(3)对比特串R16L16使用逆置换IP-1得到密文。
在DES被提出时,曾出现过很多批评,其中之一就是针对S盒。
DES里的所有计算,除了S盒,全是线性的也就是说,计算两个输出的异或与先将两个对应输入异或再计算其输出是相同的。
作为非线性部分,S盒对密码体制的安全性至关重要。
在DES刚提出时就有人怀疑S盒里隐藏了“陷门(trapdoor)”,而美国国家安全局能够轻易的解密消息。
当然,无法否定这样的猜测,但到目前为止也没有任何证据能证明DES里有陷门。
事实上,后来表明DES里的S盒是被设计来防止模型攻击的。
对DES最中肯的批评是,密钥空间的规模是256,对实际安全而言确实太小了。
对于穷举法,一台每毫秒执行一次DES加密的计算机需要一千年才能破解密文。
然而,早在1977年Diffie和Hellman就指出,若用现有技术造一台并行机,它带有1百万个加密机,每个加密机都可以每毫秒执行一次DES 加密,那么穷举时间大约10小时。
他们估计这台计算机造价两千万。
1998年7月当EFF(Electronic Frontier Foundation)宣布一台造价不到25万美元、为特殊目的设计的“DES破译机”破译了DES时,DES终于被清楚地证明是不安全的。
三、DES算法加解密原理DES算法由加密、子密钥和解密的生成三部分组成。
现将DES算法介绍如下。
1.加密DES算法处理的数据对象是一组64比特的明文串。
设该明文串为m=m1m2…m64 (mi=0或1)。
明文串经过64比特的密钥K来加密,最后生成长度为64比特的密文E。
其加密过程图示如下:DES算法加密过程对DES算法加密过程图示的说明如下:待加密的64比特明文串m,经过IP置换(初始置换)后,得到的比特串的下标列表如下:IP58 50 42 34 26 18 10 260 52 44 36 28 20 12 462 54 46 38 30 22 14 664 56 48 40 32 24 16 857 49 41 33 25 17 9 159 51 43 35 27 19 11 361 53 45 37 29 21 13 563 55 47 39 31 23 15 7该比特串被分为32位的L0和32位的R0两部分。
R0子密钥K1(子密钥的生成将在后面讲)经过变换f(R0,K1)(f变换将在下面讲)输出32位的比特串f1,f1与L0做不进位的二进制加法运算。
运算规则为:f1与L0做不进位的二进制加法运算后的结果赋给R1,R0则原封不动的赋给L1。
L1与R0又做与以上完全相同的运算,生成L2,R2……一共经过16次运算。
最后生成R16和L16。
其中R16为L15与f(R15,K16)做不进位二进制加法运算的结果,L16是R15的直接赋值。
R16与L16合并成64位的比特串。
值得注意的是R16一定要排在L16前面。
R16与L16合并后成的比特串,经过置换IP-1(终结置换)后所得比特串的下标列表如下:IP-1 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-1后生成的比特串就是密文e.。
变换f(Ri-1,Ki):它的功能是将32比特的输入再转化为32比特的输出。
其过程如图所示:f变换说明:输入Ri-1(32比特)经过变换E(扩展置换E)后,膨胀为48比特。
膨胀后的比特串的下标列表如下: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膨胀后的比特串分为8组,每组6比特。
各组经过各自的S盒后,又变为4比特(具体过程见后),合并后又成为32比特。
该32比特经过P变换(压缩置换P)后,其下标列表如下: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经过P变换后输出的比特串才是32比特的f(Ri-1,Ki).S盒的变换过程: 任取一S盒。
见图:在其输入b1,b2,b3,b4,b5,b6中,计算出x=b1*2+b6, y=b5+b4*2+b3*4+b2*8,再从Si表中查出x 行,y 列的值Sxy。
将Sxy化为二进制,即得Si盒的输出。
(S表如图所示)以上是DES算法加密原理加密过程实现(JAVA主要源代码)●输入64位明文串,经过IP置换:for (i = 0; i < 64; i++) {M[i] = timeData[IP[i] - 1];}●迭代(由于各次迭代的方法相同只是输入输出不同,因此以任意一次为例):首先进行S盒的运算。
输入32位比特串, 经过E变换,由32位变为48位:for (i = 0; i < 48; i++) {RE[i] = R0[E[i] - 1];与keyarray[times][i]按位作不进位加法运:RE[i] = RE[i] + keyarray[times][i];if (RE[i] == 2) {RE[i] = 0;}48位分成8组:for(i=0;i<8;i++){for(j=0;j<6;j++){S[i][j]=RE[(i*6)+j];}}经过S盒,得到8个数:sBoxData[i] = S_Box[i][(S[i][0] << 1) + S[i][5]][(S[i][1] << 3)+ (S[i][2] << 2) + (S[i][3] << 1) + S[i][4]];将8个数变换输出二进制:for (j = 0; j < 4; j++) {sValue[((i * 4) + 3) - j] = sBoxData[i] % 2;sBoxData[i] = sBoxData[i] / 2;}经过P变换:RP[i] = sValue[P[i] - 1];至此,S盒运算完成左右交换:L1[i] = R0[i];R1[i] = L0[i] + RP[i];Ri为Li-1与f(R,K)进行不进位二进制加法运算结果:R1[i] = L0[i] + RP[i];if (R1[i] == 2) {R1[i] = 0; }各次迭代类似,可以依此类推。