DES算法Java实现源代码
- 格式:docx
- 大小:20.09 KB
- 文档页数:10
DES加密算法javac#项⽬中⽤到的数据加密⽅式是ECB模式的DES加密得到的⼗六进制字符串。
技术⽀持让写⼀个.net版的加密算法。
这⾥做⼀下记录。
java版:16进制使⽤的是bouncycastle。
import com.emaxcard.codec.CodecException;import com.emaxcard.codec.Hex;import sun.misc.BASE64Encoder;import javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;public class DESEncrypt {public static String encodeECB(String src, String key) throws CodecException {try {SecretKey deskey = new SecretKeySpec(key.getBytes("UTF-8"), "DESede");Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, deskey);byte[] cipherInfo = cipher.doFinal(src.getBytes("UTF-8"));System.out.println("cipherInfo:"+new BASE64Encoder().encode(cipherInfo));return Hex.encode(cipherInfo);} catch (Exception var5) {throw new CodecException(var5);}}public static String decodeECB(String src, String key) throws CodecException {try {SecretKey deskey = new SecretKeySpec(key.getBytes("UTF-8"), "DESede");Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, deskey);byte[] decodeRes = cipher.doFinal(Hex.decode(src));return new String(decodeRes, "UTF-8");} catch (Exception var5) {throw new CodecException(var5);}}}public class Hex {public Hex() {}public static byte[] decode(String data) throws CodecException {try {return org.bouncycastle.util.encoders.Hex.decode(data);} catch (Exception var2) {throw new CodecException(var2.getMessage(), var2);}}public static String encode(byte[] data) {return new String(org.bouncycastle.util.encoders.Hex.encode(data));}public static void main(String[] args) throws CodecException {System.out.println(encode("a张y".getBytes()));System.out.println(new String(decode("")));}}.net(c#)版:using System;using System.IO;using System.Security.Cryptography;using System.Text;namespace ConsoleApplication1{class DESEncrypt{public static string encodeECB(string encryptString, String key){byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));byte[] keyIV = keyBytes;byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);DESCryptoServiceProvider provider = new DESCryptoServiceProvider();provider.Mode = CipherMode.ECB;provider.Padding = PaddingMode.PKCS7;MemoryStream mStream = new MemoryStream();CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length);cStream.FlushFinalBlock();//return Convert.ToBase64String(mStream.ToArray());return Hex.encode(mStream.ToArray());}public static string DesDecrypt(string decryptString, String key){byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));byte[] keyIV = keyBytes;//byte[] inputByteArray = Convert.FromBase64String(decryptString);byte[] inputByteArray = Hex.decode(decryptString);DESCryptoServiceProvider provider = new DESCryptoServiceProvider();provider.Mode = CipherMode.ECB;provider.Padding = PaddingMode.PKCS7;MemoryStream mStream = new MemoryStream();CryptoStream cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIV), CryptoStreamMode.Write); cStream.Write(inputByteArray, 0, inputByteArray.Length);cStream.FlushFinalBlock();return Encoding.UTF8.GetString(mStream.ToArray());}}}using System;using System.Globalization;using System.Text;namespace ConsoleApplication1{sealed class Hex{public static byte[] decode(String mHex){mHex = mHex.Replace("", "");if (mHex.Length <= 0) return null;byte[] vBytes = new byte[mHex.Length / 2];for (int i = 0; i < mHex.Length; i += 2)if (!byte.TryParse(mHex.Substring(i, 2), NumberStyles.HexNumber, null, out vBytes[i / 2]))vBytes[i / 2] = 0;return vBytes;}public static String encode(byte[] data){//** 以下两种⽅式都可以//⽅式1StringBuilder hexString = new StringBuilder();for (int i = 0; i < data.Length; i++){hexString.AppendFormat("{0:x2}", data[i]); //System.Convert.ToString(data[i], 16);}return hexString.ToString();//⽅式2//return BitConverter.ToString(data).Replace("-", "").ToLower();}}}BitConverter.ToString⽅法签名://// 摘要:// 将指定的字节数组的每个元素的数值转换为它的等效⼗六进制字符串表⽰形式。
DES加密和解密java代码在说DES加密算法之前,我们⾸先了解⼏个基本概念:1. 明⽂:明⽂是指没有经过加密的数据。
⼀般⽽⾔,明⽂都是等待传输的数据。
由于没有经过加密,明⽂很容易被识别与破解,因此在传输明⽂之前必须进⾏加密处理。
2. 密⽂:密⽂只是明⽂经过某种加密算法⽽得到的数据,通常密⽂的形式复杂难以识别及理解。
3. 密钥:密钥是⼀种参数,它是在明⽂转换为密⽂或将密⽂转换为明⽂的算法中输⼊的参数。
4. 对称加密:通信双⽅同时掌握⼀个密钥,加密解密都是由⼀个密钥完成的(即加密密钥等于解密密钥,加解密密钥可以相互推倒出来)。
双⽅通信前共同拟定⼀个密钥,不对第三⽅公开。
5. 分组加密:分组密码是将明⽂分成固定长度的组,每⼀组都采⽤同⼀密钥和算法进⾏加密,输出也是固定长度的密⽂。
好了了解这些以后,我们再来说DES加密算法。
DES 算法是⼀种常见的分组加密算法,由IBM公司在1971年提出。
DES 算法是分组加密算法的典型代表,同时也是应⽤最为⼴泛的对称加密算法。
下⾯我们详细介绍下:1.分组长度:DES 加密算法中,明⽂和密⽂为 64 位分组。
密钥的长度为 64 位,但是密钥的每个第⼋位设置为奇偶校验位,因此密钥的实际长度为56位。
2.加密流程:DES 加密算法⼤致分为 4 步:初始置换、⽣成⼦密钥、迭代过程、逆置换。
代码如下:需特别注意:不要使⽤JDK中⾃带的sun.misc.BASE64Decoder类去做BASE64,该类会在最后⾯多加换⾏。
⽽应使⽤apache中的mons.codec.binary.Base64这个类来做base64加密。
(待验证)import javax.crypto.Cipher;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import javax.crypto.spec.IvParameterSpec;import java.security.Key;import java.security.SecureRandom;import mons.codec.binary.Base64;public class DESUtil {// 偏移变量,固定占8位字节private final static String IV_PARAMETER = "12345678";// 字符编码public static final String CHARSET_UTF8 = "UTF-8";// 加密算法DESpublic static final String DES = "DES";// 电话本模式public static final String DES_ECB = "DES/ECB/PKCS5Padding";// 加密块链模式--推荐public static final String DES_CBC = "DES/CBC/PKCS5Padding";// 测试public static void main(String args[]) {// 待加密内容String str = "false";// 密码,长度要是8的倍数String password = "87654321";String result = DESUtil.encryptCBC(password, str);System.out.println("加密后:" + new String(result));// 直接将如上内容解密try {String decryResult = DESUtil.decryptCBC(password, result);System.out.println("解密后:" + new String(decryResult));} catch (Exception e1) {e1.printStackTrace();}}/*** ⽣成key** @param password* @return* @throws Exception*/private static Key generateKey(String password) throws Exception {DESKeySpec dks = new DESKeySpec(password.getBytes(CHARSET_UTF8));SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);return keyFactory.generateSecret(dks);}/*** DES加密字符串--ECB格式** @param password* 加密密码,长度不能够⼩于8位* @param data* 待加密字符串* @return加密后内容*/public static String encryptECB(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(DES_ECB);cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());byte[] bytes = cipher.doFinal(data.getBytes(CHARSET_UTF8));// JDK1.8及以上可直接使⽤Base64,JDK1.7及以下可以使⽤BASE64Encoder return new String(Base64.encodeBase64(bytes));} catch (Exception e) {e.printStackTrace();return data;}}/*** DES解密字符串--ECB格式** @param password* 解密密码,长度不能够⼩于8位* @param data* 待解密字符串* @return解密后内容*/public static String decryptECB(String password, String data)throws Exception {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(DES_ECB);cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());return new String(cipher.doFinal(Base64.decodeBase64(data.getBytes(CHARSET_UTF8))), CHARSET_UTF8);}/*** DES加密字符串-CBC加密格式** @param password* 加密密码,长度不能够⼩于8位* @param data* 待加密字符串* @return加密后内容*/public static String encryptCBC(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(DES_CBC);IvParameterSpec spec = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET_UTF8));cipher.init(Cipher.ENCRYPT_MODE, secretKey, spec);byte[] bytes = cipher.doFinal(data.getBytes(CHARSET_UTF8));// JDK1.8及以上可直接使⽤Base64,JDK1.7及以下可以使⽤BASE64Encoder return new String(Base64.encodeBase64(bytes));} catch (Exception e) {e.printStackTrace();return data;}}/*** DES解密字符串--CBC格式** @param password* 解密密码,长度不能够⼩于8位* @param data* 待解密字符串* @return解密后内容*/public static String decryptCBC(String password, String data) throws Exception {Key secretKey = generateKey(password);Cipher cipher = Cipher.getInstance(DES_CBC);IvParameterSpec spec = new IvParameterSpec(IV_PARAMETER.getBytes(CHARSET_UTF8));cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);return new String(cipher.doFinal(Base64.decodeBase64(data.getBytes(CHARSET_UTF8))), CHARSET_UTF8); }}。
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算法,解密出错。
DES可逆加密算法JAVA源代码下面是一个实现DES可逆加密算法的Java源代码。
该代码共1281个字符(字母、符号、数字)。
```javaimport javax.crypto.Cipher;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;import java.nio.charset.StandardCharsets;import java.util.Base64;public class DESprivate static final String key = "mysecret"; // 设置密钥public static void main(String[] args)String plainText = "Hello, World!"; // 要进行加密的明文String encryptedText = encrypt(plainText);System.out.println("Encrypted text: " + encryptedText);String decryptedText = decrypt(encryptedText);System.out.println("Decrypted text: " + decryptedText);}public static String encrypt(String plainText)tryDESKeySpec desKeySpec = newDESKeySpec(key.getBytes(StandardCharsets.UTF_8));SecretKeyFactory keyFactory =SecretKeyFactory.getInstance("DES");SecretKey secretKey = keyFactory.generateSecret(desKeySpec);Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, secretKey);byte[] encryptedBytes =cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder(.encodeToString(encryptedBytes);} catch (Exception e)e.printStackTrace(;}return null;}public static String decrypt(String encryptedText)tryDESKeySpec desKeySpec = newDESKeySpec(key.getBytes(StandardCharsets.UTF_8));SecretKeyFactory keyFactory =SecretKeyFactory.getInstance("DES");SecretKey secretKey = keyFactory.generateSecret(desKeySpec);Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, secretKey);byte[] decryptedBytes =cipher.doFinal(Base64.getDecoder(.decode(encryptedText));return new String(decryptedBytes, StandardCharsets.UTF_8);} catch (Exception e)e.printStackTrace(;}return null;}```该代码使用DES算法进行加密和解密,使用密钥"mysecret"对数据进行处理。
目录摘要 (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语言下可以导入org.apache前缀的类库,apache组织给出了org.apache.codec类库,将基本的加密和解密方法打包成现成方法,并且提供了DES算法必备的S盒。
所以这个实现方法会采用org.apache.codec类库,采用结合源代码的方式进行编写。
工程名为ZDESAl即DES Algorithm,下面包含两个类,DESCoder负责生成密钥,DESCoderTest负责进行密钥的左移、置换选择,扩充等操作。
下面给出DESCoder类的设计思路和源代码:import java.security.Key;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.SecretKeyFactory;import javax.crypto.spec.DESKeySpec;/***DES安全编码组件*@author Hawke7*@version 1.0*/public abstract class DESCoder {/***密钥算法<br>*Java6只支持56位密钥<br>*Bouncy Castle支持64位密钥*/public static final String KEY_ALGORITHM = "DES";/***加密/解密算法/工作模式/填充方式*/public static final String CIPHER_ALGORITHM= "DES/ECB/PKCS5Padding";/***转换密钥*@param key二进制密钥*@return key二进制密钥*@throws Exception*/private static Key toKey(byte[] key) throws Exception {// 实例化DES密钥材料DESKeySpec dks = new DESKeySpec(key);// 实例化秘密密钥工厂SecretKeyFactory keyFactory =SecretKeyFactory.getInstance(KEY_ALGORITHM);// 生成私密密钥SecretKey secretKey = keyFactory.generateSecret(dks);return secretKey;}/***解密*@param data待解密数据*@param key密钥*@return byte[]解密数据*@throws Exception*/public static byte[] decrypt(byte[] data, byte[] key) throws Exception {// 还原密钥Key k = toKey(key);// 实例化Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);// 初始化,设置为解密模式cipher.init(Cipher.DECRYPT_MODE, k);// 执行操作return cipher.doFinal(data);}/***加密*@param data待加密数据*@param key密钥*@return byte[]加密数据*@throws Exception*/public static byte[] encrypt(byte[] data, byte[] key) throws Exception {// 还原密钥Key k = toKey(key);// 实例化Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);// 初始化,设置为解密模式cipher.init(Cipher.ENCRYPT_MODE, k);// 执行操作return cipher.doFinal(data);}/***生成密钥<br>*Java6只支持56位密钥<br>*Bouncy Castle支持64位密钥<br>*@return byte[]二进制密钥*@throws Exception*/public static byte[] initKey() throws Exception {/** 实例化密钥生成器* 若要使用64位密钥注意替换* 将下述代码中的* KeyGenerator.getInstance(CIPHER_ALGORITHM);* 替换为* KeyGenerator.getInstance(CIPHER_ALGORITHM, "BC");*/KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);/** 初始化密钥生成器* 若要使用64位密钥注意替换* 将下面代码kg.init(56)* 替换为kg.init(64)*/kg.init(56);// 生成私密密钥SecretKey secretKey = kg.generateKey();// 获得密钥的二进制编码形式return secretKey.getEncoded();}}首先DESCoder要定义成抽象类,因为其中全部是static静态方法toKey,toKey初始化密钥材料,并且实例化密钥工厂,因为DES算法要进行16轮迭代,所以工厂每一次都要给出不同的密钥,从而增强雪崩效应。
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加密算法,于是我在查阅了相关资料后有了以下成果。
⾸先,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的编程实现一、实验目的在本实验中,用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”。
DES算法源代码DES(Data Encryption Standard)是一种对称加密算法,使用相同的密钥对数据进行加密和解密。
它在1977年被美国联邦信息处理标准(FIPS)采纳为联邦标准,至今仍然在很多场景中广泛使用。
以下是一个使用Python实现DES算法的源代码:```pythonfrom Crypto.Cipher import DESfrom Crypto.Random import get_random_bytes# 生成一个由字节(byte)组成的密钥def generate_key(:return get_random_bytes(8)#使用给定的密钥加密数据def encrypt(key, data):cipher = DES.new(key, DES.MODE_ECB)#如果数据的长度不是8的倍数,需要进行填充if len(data) % 8 != 0:data += b'\x00' * (8 - len(data) % 8)ciphertext = cipher.encrypt(data)return ciphertext#使用给定的密钥解密数据def decrypt(key, ciphertext):cipher = DES.new(key, DES.MODE_ECB)data = cipher.decrypt(ciphertext)#去除填充数据data = data.rstrip(b'\x00')return data#测试代码key = generate_keyplaintext = b'This is a test message.'ciphertext = encrypt(key, plaintext)decrypted_text = decrypt(key, ciphertext)print('Key:', key)print('Plaintext:', plaintext)print('Ciphertext:', ciphertext)print('Decrypted Text:', decrypted_text)```这段代码使用Python的`Crypto`库中的`DES`模块来实现DES加密和解密。
package des;/*** 加密过程:* 1.初始置换IP:将明文顺序打乱重新排列,置换输出为64位。
* 2.将置换输出的64位明文分成左右凉拌,左一半为L0,右一半称为R0,各32位。
* 3。
计算函数的16轮迭代。
* a)第一轮加密迭代:左半边输入L0,右半边输入R0:由轮函数f实现子密钥K1对R0的加密,*结果为32位数据组f(R0,K1),*b)第二轮加密迭代:左半边输入L1=R0,右半边输入R1=L0⊕f(R0,K1),由轮函数f实现子密钥* K2对R1的加密,结果为32位数据组f(R1,K2),f(R1,K2)与L1模2相加,得到一个32为数据组L1⊕f(R1,K2).* c)第3到16轮迭代分别用密钥K3,K4……K16进行。
4.再经过逆初始置换IP-1,将数据打乱重排,生成64位密文。
** 子密钥生成过程:* 1.将64位的密钥经过PC-1置换生成56位密钥。
* 2.将56位的密钥分成左右两部分,分别进行移位操作(一共进行16轮),产生16个56位长度的子密钥。
* 3.将16个56位的子密钥分别进行PC-2置换生成16个48位的子密钥。
** 轮函数f的工作过程:* 1.在第i次加密迭代过程中,扩展置换E对32位的Ri-1的各位通过置换表置换为48位的输出。
* 2.将该48位的输出与子密钥Ki进行异或操作,运算结果经过S盒代换运算,得到一个32位比特的输出。
* 3。
该32位比特输出再经过P置换表进行P运算,将其各位打乱重排,生成32位的输出。
** @author Ouyang**/public class Des {int[] byteKey;public Des(int[] byteKey) {this.byteKey = byteKey;}private static final int[] 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 }; // 64private static final int[] 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 }; // 64private static final int[] PC_1 = { 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 }; // 56private static final int[] PC_2 = { 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 }; // 48private static final int[] 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 }; // 48 private static final int[] 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 }; // 32private static final int[][][] S_Box = {// S-盒{// S_Box[1]{ 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 } }, { // S_Box[2]{ 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 } }, { // S_Box[3]{ 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 } }, { // S_Box[4]{ 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 } }, { // S_Box[5]{ 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 } }, { // S_Box[6]{ 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 } }, { // S_Box[7]{ 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 } }, { // S_Box[8]{ 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 } } }; private static final int[] LeftMove = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };/*** 对64位明文进行IP置换处理,* @param data 需要经过初始IP置换的明文* @return 64位经过置换处理的明文*/public int[] IpReplace(int[] data){int[] ipMingWen = new int[64];for (int i = 0; i < ipMingWen.length; i++) {ipMingWen[i] = data[IP[i]-1];}return ipMingWen;}public static int[] StringToBits(String data){byte[] test = data.getBytes();int[] IntVa = new int[64];int[] IntDa = new int[8];for (int i = 0; i < 8; i++) {IntDa[i] = test[i];if (IntDa[i] < 0) {IntDa[i] += 256;IntDa[i] %= 256;}}for (int i = 0; i < 8; i++) {for (int j = 0; j < 8; j++) {IntVa[((i * 8) + 7) - j] = IntDa[i] % 2;IntDa[i] = IntDa[i] / 2;}}return IntVa;}/*** 功能:对给定的数组按照offset指定的位数进行循环左移,输出经过左移后的数组* 作用:将经过pc-1置换处理后的56位密钥先分成左右各28位,然后根据左移表要求对密钥进行左移* @param key 经过pc-1处理后的56位密钥* @return 单个56位的子密钥(初步,未经过pc2置换)*/public int[] LeftMove(int[] key,int offset){int[] subKey = new int[56];int[] C0 = new int[28];int[] D0 = new int[28];int[] C1 = new int[28];int[] D1 = new int[28];for (int i = 0; i < 28; i++) {C0[i] = key[i];D0[i] = key[i+28];}if(offset == 1){for(int i = 0; i < 27;i++){C1[i] = C0[i+1];D1[i] = D0[i+1];}C1[27] = C0[0];D1[27] = D0[0];}else if(offset == 2){for (int i = 0; i < 26; i++) {C1[i] = C0[i+2];D1[i] = D0[i+2];}C1[26] = C0[0];D1[26] = D0[0];C1[27] = C0[1];D1[27] = D0[1];}for (int i = 0; i < 28; i++) {subKey[i] = C1[i];subKey[i+28] = D1[i];}return subKey;}/*** 根据经过PC-1置换后的56位密钥生成16个56位的子密钥。