Java 利用DES加密/解密

概要:

本实例主要实现对指定文件进行DES加/解密的过程。一段文字被加密后,输出的都是一些乱码。这样就很好地加密了文字,并且解密后的文字与原文字相同。

| |目录

技术要点

利用DES加密/解密的技术要点如下:

  • java.nio.channels.FileChannel的用法。

  • 标识的应用。

  • Des加密算法。

代码实现

DES_File.java

package net.xsoftlab.baike;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
public class DES_File {
	private static final boolean isenc = true; // 加密
	private static final boolean isdec = false; // 解密
	private String sourceFileName; // 源文件的名称
	private String targetFileName; // 目标文件的名称
	private String inKey;// 密钥
	private boolean encdes;// 加密解密标识,true表示加密,false表示解密
	private File sourceFile;// 源文件
	private File targetFile;// 目标文件
	private Des_SI des;// 选择si的功能函数类:Des_SI
	private void get_FilePath() {// 获取文件的路径
		String pathname;
		int pos = sourceFileName.lastIndexOf("/");
		pathname = sourceFileName.substring(0, pos); // 取得文件路径
		File dir = new File(pathname);// 根据取得的路径创建方件对象
		if (!dir.exists()) { // 判断是否存在
			System.out.println(pathname + " is not exist");
			System.exit(1);
		} else if (!dir.isDirectory()) { // 判断是否为目录
			System.out.println(pathname + " is not a directory");
			System.exit(1);
		}
		pos = targetFileName.lastIndexOf("/");
		pathname = targetFileName.substring(0, pos);
		dir = new File(pathname);
		if (!dir.exists()) {// 判断该目录是否存在
			if (!dir.mkdirs()) {
				System.out.println("can not creat directory:" + pathname);
				System.exit(1);
			}
		} else if (!dir.isDirectory()) {
			System.out.println(pathname + " is not a directory");
			System.exit(1);
		}
	}
	private static int Channel_Buf(FileChannel channel, ByteBuffer buf)
			throws IOException {
		long byteLeft = channel.size() - channel.position();
		if (byteLeft == 0L)
			return -1;
		buf.position(0);// 设置此文件通道的文件位置为0
		buf.limit(buf.position() + (byteLeft < 8 ? (int) byteLeft : 8));// 设置缓冲区的限制
		return channel.read(buf);// 将字节序列从此通道读入给定的缓冲区
	}
	private void Source_Target(boolean flag) {// 根据flag标识进行相应的操作
		if (flag)
			System.out.println("DES加密操作开始…………");
		else
			System.out.println("DES解密操作开始…………");
		des = new Des_SI(inKey);// 将密钥转换成二进制
		FileOutputStream outputFile = null;
		try {
			outputFile = new FileOutputStream(sourceFile, true);// 创建文件输出流
		} catch (java.io.FileNotFoundException e) {
			System.out.println(e.getStackTrace());
		}
		FileChannel outChannel = outputFile.getChannel();// 创建文件通道
		try {
			if (outChannel.size() % 2 != 0) {
				ByteBuffer bufTemp = ByteBuffer.allocate(1);
				bufTemp.put((byte) 32);
				bufTemp.flip();
				outChannel.position(outChannel.size());
				outChannel.write(bufTemp);
				bufTemp.clear();
			}
		} catch (Exception ex) {
			System.out.println(ex.getStackTrace());
			System.exit(1);
		}
		FileInputStream inFile = null;
		try {
			inFile = new FileInputStream(sourceFile);
		} catch (java.io.FileNotFoundException e) {
			System.out.println(e.getStackTrace());
		}
		outputFile = null;
		try {
			outputFile = new FileOutputStream(targetFile, true);
		} catch (java.io.FileNotFoundException e) {
			System.out.println(e.getStackTrace());
		}
		FileChannel inChannel = inFile.getChannel();
		outChannel = outputFile.getChannel();
		ByteBuffer inBuf = ByteBuffer.allocate(8);
		ByteBuffer outBuf = ByteBuffer.allocate(8);
		try {
			String sourceStr;
			String targetStr;
			while (true) {
				if (Channel_Buf(inChannel, inBuf) == -1)
					break;
				sourceStr = ((ByteBuffer) (inBuf.flip())).asCharBuffer()
						.toString();
				inBuf.clear();
				if (flag) { // 若为true,则加密
					targetStr = des.enc(sourceStr, sourceStr.length());
				} else { // 若为false,则解密
					targetStr = des.dec(sourceStr, sourceStr.length());
				}
				outBuf.clear();
				if (targetStr.length() == 4) {
					for (int i = 0; i < 4; i++) {
						outBuf.putChar(targetStr.charAt(i));
					}
					outBuf.flip();
				} else {
					outBuf.position(0);
					outBuf.limit(2 * targetStr.length());
					for (int i = 0; i < targetStr.length(); i++) {
						outBuf.putChar(targetStr.charAt(i));
					}
					outBuf.flip();
				}
				try {
					outChannel.write(outBuf);
					outBuf.clear();
				} catch (java.io.IOException ex) {
					System.out.println(ex.getStackTrace());
				}
			}
			System.out.println("输入流的文件通道的大小为:" + inChannel.size());
			System.out.println("输出流的文件通道的大小为:" + outChannel.size());
			System.out.println("EOF分析成功完成
");
			inFile.close();
			outputFile.close();
		} catch (java.io.IOException e) {
			System.out.println(e.getStackTrace());
			System.exit(1);
		}
	}
	public DES_File(String sourceFileName, String targetFileName, String inKey,
			boolean encdes) {
		this.sourceFileName = sourceFileName;
		this.targetFileName = targetFileName;
		this.encdes = encdes;
		get_FilePath();
		sourceFile = new File(sourceFileName);
		targetFile = new File(targetFileName);
		this.inKey = inKey;
		if (encdes == isenc)
			Source_Target(isenc); // 执行加密操作
		else
			Source_Target(isdec); // 执行解密操作
	}
	public static void main(String[] args) {
		String srcfile = System.getProperty("user.dir") + "/file.doc"; // 原始文件
		String cypfile = System.getProperty("user.dir") + "/encrypt.doc"; // 加密后的密文文件
		String trgfile = System.getProperty("user.dir") + "/decrypt.doc"; // 解密后文件
		String passWord = "ABCD4567"; // 工作密匙 为8个字符
		new DES_File(srcfile, cypfile, passWord, true);
		new DES_File(cypfile, trgfile, passWord, false);
	}
}

Des_SI.java

package net.xsoftlab.baike;
public class Des_SI {// 选择si的功能函数
	protected static byte[][] s1 = {// 表s1
	{ 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 } };
	protected static byte[][] s2 = {// 表s2
	{ 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 } };
	protected static byte[][] s3 = {// 表s3
	{ 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 } };
	protected static byte[][] s4 = {// 表s4
	{ 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 } };
	protected static byte[][] s5 = { // 表s5
	{ 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 } };
	protected static byte[][] s6 = {// 表s6
	{ 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 } };
	protected static byte[][] s7 = {// 表s7
	{ 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 } };
	protected static byte[][] s8 = {// 表s8
	{ 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 } };
	protected static byte[] binary = { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0,
			0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 0,
			0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 1,
			1, 1, 0, 1, 1, 1, 1 };// 用于 S盒查找以确定对应的4位二进制数据
	protected byte[] tempData = new byte[64];// 存储将要加密的明文或将要解密的密文
	protected String Srcdata;
	protected String Tagdata;
	protected byte[] bufout = new byte[64];// 用于数据变换中转
	// 最终生成的密文或解密所得的明文
	protected byte[] output = new byte[64];
	protected byte[] Ln = new byte[32];
	protected byte[] Rn = new byte[32];
	protected byte[] LR = new byte[32];
	protected byte[] ER = new byte[48];
	protected byte[] temp = new byte[32];
	protected byte[] result = new byte[8];
	protected byte[] ki;
	protected String key;
	protected int readLen;
	protected boolean encFlag; // 1为加密,0为解密
	protected GetSubKey subKey;
	protected void Char4Tobit64(String data) {
		for (int i = 0; i < 64; i++) {
			tempData[i] = 0;
		}
		// 将4个字符的unicode码数据转换成64位数据
		for (int i = 0; i < readLen; i++) {
			int j = data.charAt(i);
			tempData[16 * i + 0] = (byte) ((j / 32768) % 2);
			tempData[16 * i + 1] = (byte) ((j / 16384) % 2);
			tempData[16 * i + 2] = (byte) ((j / 8192) % 2);
			tempData[16 * i + 3] = (byte) ((j / 4096) % 2);
			tempData[16 * i + 4] = (byte) ((j / 2048) % 2);
			tempData[16 * i + 5] = (byte) ((j / 1024) % 2);
			tempData[16 * i + 6] = (byte) ((j / 512) % 2);
			tempData[16 * i + 7] = (byte) ((j / 256) % 2);
			tempData[16 * i + 8] = (byte) ((j / 128) % 2);
			tempData[16 * i + 9] = (byte) ((j / 64) % 2);
			tempData[16 * i + 10] = (byte) ((j / 32) % 2);
			tempData[16 * i + 11] = (byte) ((j / 16) % 2);
			tempData[16 * i + 12] = (byte) ((j / 8) % 2);
			tempData[16 * i + 13] = (byte) ((j / 4) % 2);
			tempData[16 * i + 14] = (byte) ((j / 2) % 2);
			tempData[16 * i + 15] = (byte) (j % 2);
		}
	}
	protected void Bit64To4Char() {
		int j;
		char ch;
		StringBuffer strbuf = new StringBuffer();
		for (int i = 0; i < 4; i++) {
			j = 0;
			j = 32768 * output[16 * i + 0] + 16384 * output[16 * i + 1] + 8192
					* output[16 * i + 2] + 4096 * output[16 * i + 3] + 2048
					* output[16 * i + 4] + 1024 * output[16 * i + 5] + 512
					* output[16 * i + 6] + 256 * output[16 * i + 7] + 128
					* output[16 * i + 8] + 64 * output[16 * i + 9] + 32
					* output[16 * i + 10] + 16 * output[16 * i + 11] + 8
					* output[16 * i + 12] + 4 * output[16 * i + 13] + 2
					* output[16 * i + 14] + output[16 * i + 15];
			ch = (char) j;
			strbuf.append(ch);
		}
		Tagdata = strbuf.toString();
	}
	protected void IP() {
		/* 初始数据置换 */
		bufout[0] = tempData[57];
		bufout[1] = tempData[49];
		bufout[2] = tempData[41];
		bufout[3] = tempData[33];
		bufout[4] = tempData[25];
		bufout[5] = tempData[17];
		bufout[6] = tempData[9];
		bufout[7] = tempData[1];
		bufout[8] = tempData[59];
		bufout[9] = tempData[51];
		bufout[10] = tempData[43];
		bufout[11] = tempData[35];
		bufout[12] = tempData[27];
		bufout[13] = tempData[19];
		bufout[14] = tempData[11];
		bufout[15] = tempData[3];
		bufout[16] = tempData[61];
		bufout[17] = tempData[53];
		bufout[18] = tempData[45];
		bufout[19] = tempData[37];
		bufout[20] = tempData[29];
		bufout[21] = tempData[21];
		bufout[22] = tempData[13];
		bufout[23] = tempData[5];
		bufout[24] = tempData[63];
		bufout[25] = tempData[55];
		bufout[26] = tempData[47];
		bufout[27] = tempData[39];
		bufout[28] = tempData[31];
		bufout[29] = tempData[23];
		bufout[30] = tempData[15];
		bufout[31] = tempData[7];
		bufout[32] = tempData[56];
		bufout[33] = tempData[48];
		bufout[34] = tempData[40];
		bufout[35] = tempData[32];
		bufout[36] = tempData[24];
		bufout[37] = tempData[16];
		bufout[38] = tempData[8];
		bufout[39] = tempData[0];
		bufout[40] = tempData[58];
		bufout[41] = tempData[50];
		bufout[42] = tempData[42];
		bufout[43] = tempData[34];
		bufout[44] = tempData[26];
		bufout[45] = tempData[18];
		bufout[46] = tempData[10];
		bufout[47] = tempData[2];
		bufout[48] = tempData[60];
		bufout[49] = tempData[52];
		bufout[50] = tempData[44];
		bufout[51] = tempData[36];
		bufout[52] = tempData[28];
		bufout[53] = tempData[20];
		bufout[54] = tempData[12];
		bufout[55] = tempData[4];
		bufout[56] = tempData[62];
		bufout[57] = tempData[54];
		bufout[58] = tempData[46];
		bufout[59] = tempData[38];
		bufout[60] = tempData[30];
		bufout[61] = tempData[22];
		bufout[62] = tempData[14];
		bufout[63] = tempData[6];
	}
	protected void XOR(byte[] op1, byte[] op2) {
		int len = op1.length;
		for (int i = 0; i < len; i++) {
			op1[i] = (byte) (op1[i] ^ op2[i]);
		}
	}
	protected void expand32To48bit(byte[] op) {
		/* 字节交换 */
		ER[0] = op[31];
		ER[1] = op[0];
		ER[2] = op[1];
		ER[3] = op[2];
		ER[4] = op[3];
		ER[5] = op[4];
		ER[6] = op[3];
		ER[7] = op[4];
		ER[8] = op[5];
		ER[9] = op[6];
		ER[10] = op[7];
		ER[11] = op[8];
		ER[12] = op[7];
		ER[13] = op[8];
		ER[14] = op[9];
		ER[15] = op[10];
		ER[16] = op[11];
		ER[17] = op[12];
		ER[18] = op[11];
		ER[19] = op[12];
		ER[20] = op[13];
		ER[21] = op[14];
		ER[22] = op[15];
		ER[23] = op[16];
		ER[24] = op[15];
		ER[25] = op[16];
		ER[26] = op[17];
		ER[27] = op[18];
		ER[28] = op[19];
		ER[29] = op[20];
		ER[30] = op[19];
		ER[31] = op[20];
		ER[32] = op[21];
		ER[33] = op[22];
		ER[34] = op[23];
		ER[35] = op[24];
		ER[36] = op[23];
		ER[37] = op[24];
		ER[38] = op[25];
		ER[39] = op[26];
		ER[40] = op[27];
		ER[41] = op[28];
		ER[42] = op[27];
		ER[43] = op[28];
		ER[44] = op[29];
		ER[45] = op[30];
		ER[46] = op[31];
		ER[47] = op[0];
	}
	protected void sBox() {
		int valindex;
		valindex = s1[2 * ER[0] + ER[5]][2 * (2 * (2 * ER[1] + ER[2]) + ER[3])
				+ ER[4]];
		valindex = valindex * 4;
		temp[0] = (byte) binary[0 + valindex];
		temp[1] = (byte) binary[1 + valindex];
		temp[2] = (byte) binary[2 + valindex];
		temp[3] = (byte) binary[3 + valindex];
		valindex = s2[2 * ER[6] + ER[11]][2 * (2 * (2 * ER[7] + ER[8]) + ER[9])
				+ ER[10]];
		valindex = valindex = valindex * 4;
		temp[4] = (byte) binary[0 + valindex];
		temp[5] = (byte) binary[1 + valindex];
		temp[6] = (byte) binary[2 + valindex];
		temp[7] = (byte) binary[3 + valindex];
		valindex = s3[2 * ER[12] + ER[17]][2
				* (2 * (2 * ER[13] + ER[14]) + ER[15]) + ER[16]];
		valindex = valindex = valindex * 4;
		temp[8] = (byte) binary[0 + valindex];
		temp[9] = (byte) binary[1 + valindex];
		temp[10] = (byte) binary[2 + valindex];
		temp[11] = (byte) binary[3 + valindex];
		valindex = s4[2 * ER[18] + ER[23]][2
				* (2 * (2 * ER[19] + ER[20]) + ER[21]) + ER[22]];
		valindex = valindex = valindex * 4;
		temp[12] = (byte) binary[0 + valindex];
		temp[13] = (byte) binary[1 + valindex];
		temp[14] = (byte) binary[2 + valindex];
		temp[15] = (byte) binary[3 + valindex];
		valindex = s5[2 * ER[24] + ER[29]][2
				* (2 * (2 * ER[25] + ER[26]) + ER[27]) + ER[28]];
		valindex = valindex = valindex * 4;
		temp[16] = (byte) binary[0 + valindex];
		temp[17] = (byte) binary[1 + valindex];
		temp[18] = (byte) binary[2 + valindex];
		temp[19] = (byte) binary[3 + valindex];
		valindex = s6[2 * ER[30] + ER[35]][2
				* (2 * (2 * ER[31] + ER[32]) + ER[33]) + ER[34]];
		valindex = valindex = valindex * 4;
		temp[20] = (byte) binary[0 + valindex];
		temp[21] = (byte) binary[1 + valindex];
		temp[22] = (byte) binary[2 + valindex];
		temp[23] = (byte) binary[3 + valindex];
		valindex = s7[2 * ER[36] + ER[41]][2
				* (2 * (2 * ER[37] + ER[38]) + ER[39]) + ER[40]];
		valindex = valindex = valindex * 4;
		temp[24] = (byte) binary[0 + valindex];
		temp[25] = (byte) binary[1 + valindex];
		temp[26] = (byte) binary[2 + valindex];
		temp[27] = (byte) binary[3 + valindex];
		valindex = s8[2 * ER[42] + ER[47]][2
				* (2 * (2 * ER[43] + ER[44]) + ER[45]) + ER[46]];
		valindex = valindex = valindex * 4;
		temp[28] = (byte) binary[0 + valindex];
		temp[29] = (byte) binary[1 + valindex];
		temp[30] = (byte) binary[2 + valindex];
		temp[31] = (byte) binary[3 + valindex];
	}
	protected void p() {
		/* Permute - P */
		Rn[0] = temp[15];
		Rn[1] = temp[6];
		Rn[2] = temp[19];
		Rn[3] = temp[20];
		Rn[4] = temp[28];
		Rn[5] = temp[11];
		Rn[6] = temp[27];
		Rn[7] = temp[16];
		Rn[8] = temp[0];
		Rn[9] = temp[14];
		Rn[10] = temp[22];
		Rn[11] = temp[25];
		Rn[12] = temp[4];
		Rn[13] = temp[17];
		Rn[14] = temp[30];
		Rn[15] = temp[9];
		Rn[16] = temp[1];
		Rn[17] = temp[7];
		Rn[18] = temp[23];
		Rn[19] = temp[13];
		Rn[20] = temp[31];
		Rn[21] = temp[26];
		Rn[22] = temp[2];
		Rn[23] = temp[8];
		Rn[24] = temp[18];
		Rn[25] = temp[12];
		Rn[26] = temp[29];
		Rn[27] = temp[5];
		Rn[28] = temp[21];
		Rn[29] = temp[10];
		Rn[30] = temp[3];
		Rn[31] = temp[24];
	}
	protected void IIP() {
		/* 初始逆置换 */
		output[0] = bufout[39];
		output[1] = bufout[7];
		output[2] = bufout[47];
		output[3] = bufout[15];
		output[4] = bufout[55];
		output[5] = bufout[23];
		output[6] = bufout[63];
		output[7] = bufout[31];
		output[8] = bufout[38];
		output[9] = bufout[6];
		output[10] = bufout[46];
		output[11] = bufout[14];
		output[12] = bufout[54];
		output[13] = bufout[22];
		output[14] = bufout[62];
		output[15] = bufout[30];
		output[16] = bufout[37];
		output[17] = bufout[5];
		output[18] = bufout[45];
		output[19] = bufout[13];
		output[20] = bufout[53];
		output[21] = bufout[21];
		output[22] = bufout[61];
		output[23] = bufout[29];
		output[24] = bufout[36];
		output[25] = bufout[4];
		output[26] = bufout[44];
		output[27] = bufout[12];
		output[28] = bufout[52];
		output[29] = bufout[20];
		output[30] = bufout[60];
		output[31] = bufout[28];
		output[32] = bufout[35];
		output[33] = bufout[3];
		output[34] = bufout[43];
		output[35] = bufout[11];
		output[36] = bufout[51];
		output[37] = bufout[19];
		output[38] = bufout[59];
		output[39] = bufout[27];
		output[40] = bufout[34];
		output[41] = bufout[2];
		output[42] = bufout[42];
		output[43] = bufout[10];
		output[44] = bufout[50];
		output[45] = bufout[18];
		output[46] = bufout[58];
		output[47] = bufout[26];
		output[48] = bufout[33];
		output[49] = bufout[1];
		output[50] = bufout[41];
		output[51] = bufout[9];
		output[52] = bufout[49];
		output[53] = bufout[17];
		output[54] = bufout[57];
		output[55] = bufout[25];
		output[56] = bufout[32];
		output[57] = bufout[0];
		output[58] = bufout[40];
		output[59] = bufout[8];
		output[60] = bufout[48];
		output[61] = bufout[16];
		output[62] = bufout[56];
		output[63] = bufout[24];
	}
	public Des_SI(String key) {
		this.key = key;
		subKey = new GetSubKey(key);
	}
	// 解密
	public String enc(String Srcdata, int readLen) {
		this.Srcdata = Srcdata;
		this.readLen = readLen;
		Char4Tobit64(Srcdata);
		IP();
		for (int i = 0; i < 32; i++) {
			Ln[i] = bufout[i]; // L0
			Rn[i] = bufout[32 + i]; // R0
		}
		for (int iter = 1; iter < 17; iter++) {
			for (int i = 0; i < 32; i++) {
				LR[i] = Ln[i];
				Ln[i] = Rn[i];
			}
			expand32To48bit(Rn); // Rn-1 expand to 48 bit save to ER[]
			switch (iter) {
			case 1:
				ki = subKey.k1;
				break;
			case 2:
				ki = subKey.k2;
				break;
			case 3:
				ki = subKey.k3;
				break;
			case 4:
				ki = subKey.k4;
				break;
			case 5:
				ki = subKey.k5;
				break;
			case 6:
				ki = subKey.k6;
				break;
			case 7:
				ki = subKey.k7;
				break;
			case 8:
				ki = subKey.k8;
				break;
			case 9:
				ki = subKey.k9;
				break;
			case 10:
				ki = subKey.k10;
				break;
			case 11:
				ki = subKey.k11;
				break;
			case 12:
				ki = subKey.k12;
				break;
			case 13:
				ki = subKey.k13;
				break;
			case 14:
				ki = subKey.k14;
				break;
			case 15:
				ki = subKey.k15;
				break;
			case 16:
				ki = subKey.k16;
				break;
			}
			XOR(ER, ki);
			sBox();
			p();
			XOR(Rn, LR);
		}
		for (int i = 0; i < 32; i++) {
			bufout[i] = Rn[i];
			bufout[32 + i] = Ln[i];
		}
		IIP();
		Bit64To4Char();
		return Tagdata;
	}
	// 加密
	public String dec(String Srcdata, int readLen) {
		this.Srcdata = Srcdata;
		this.readLen = readLen;
		Char4Tobit64(Srcdata);
		IP();
		for (int i = 0; i < 32; i++) {
			Ln[i] = bufout[i]; // L0
			Rn[i] = bufout[32 + i]; // R0
		}
		for (int iter = 1; iter < 17; iter++) {
			for (int i = 0; i < 32; i++) {
				LR[i] = Ln[i];
				Ln[i] = Rn[i];
			}
			expand32To48bit(Rn);
			// Rn-1 扩展到48bit并保存到ER[]
			switch (iter) {
			case 1:
				ki = subKey.k16;
				break;
			case 2:
				ki = subKey.k15;
				break;
			case 3:
				ki = subKey.k14;
				break;
			case 4:
				ki = subKey.k13;
				break;
			case 5:
				ki = subKey.k12;
				break;
			case 6:
				ki = subKey.k11;
				break;
			case 7:
				ki = subKey.k10;
				break;
			case 8:
				ki = subKey.k9;
				break;
			case 9:
				ki = subKey.k8;
				break;
			case 10:
				ki = subKey.k7;
				break;
			case 11:
				ki = subKey.k6;
				break;
			case 12:
				ki = subKey.k5;
				break;
			case 13:
				ki = subKey.k4;
				break;
			case 14:
				ki = subKey.k3;
				break;
			case 15:
				ki = subKey.k2;
				break;
			case 16:
				ki = subKey.k1;
				break;
			}
			XOR(ER, ki);
			sBox();
			p();
			XOR(Rn, LR);
		}
		for (int i = 0; i < 32; i++) {
			bufout[i] = Rn[i];
			bufout[32 + i] = Ln[i];
		}
		IIP();
		Bit64To4Char();
		return Tagdata;
	}
}

GetSubKey.java

package net.xsoftlab.baike;
public class GetSubKey {
	private String inKey;
	private StringBuffer keyBuf;
	private byte[] key = new byte[64]; // 保存密钥的64位二进制表示
	private byte[] kwork = new byte[56];
	private static byte[] shift = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2,
			2, 1 };
	protected byte[] k1 = new byte[48];
	protected byte[] k2 = new byte[48];
	protected byte[] k3 = new byte[48];
	protected byte[] k4 = new byte[48];
	protected byte[] k5 = new byte[48];
	protected byte[] k6 = new byte[48];
	protected byte[] k7 = new byte[48];
	protected byte[] k8 = new byte[48];
	protected byte[] k9 = new byte[48];
	protected byte[] k10 = new byte[48];
	protected byte[] k11 = new byte[48];
	protected byte[] k12 = new byte[48];
	protected byte[] k13 = new byte[48];
	protected byte[] k14 = new byte[48];
	protected byte[] k15 = new byte[48];
	protected byte[] k16 = new byte[48];
	protected byte[] kn = new byte[48];
	public GetSubKey(String inKey) {
		byte j;
		this.inKey = inKey;
		int len = inKey.length();
		keyBuf = new StringBuffer(inKey);
		if (len < 8) { // 密钥必须是8位,若小于8位不够的补空格 ,大于8位取前8位
			for (int i = 1; i <= 8 - len; i++)
				keyBuf.append("?");
		}
		inKey = keyBuf.toString();
		// 将8个字符的密钥转换成64位二进制表示
		for (int i = 0; i < 8; i++) {
			j = (byte) (inKey.charAt(i));
			key[8 * i] = (byte) ((j / 128) % 2);
			key[8 * i + 1] = (byte) ((j / 64) % 2);
			key[8 * i + 2] = (byte) ((j / 32) % 2);
			key[8 * i + 3] = (byte) ((j / 16) % 2);
			key[8 * i + 4] = (byte) ((j / 8) % 2);
			key[8 * i + 5] = (byte) ((j / 4) % 2);
			key[8 * i + 6] = (byte) ((j / 2) % 2);
			key[8 * i + 7] = (byte) (j % 2);
		}
		// 初始化键的排列顺序
		kwork[0] = key[56];
		kwork[1] = key[48];
		kwork[2] = key[40];
		kwork[3] = key[32];
		kwork[4] = key[24];
		kwork[5] = key[16];
		kwork[6] = key[8];
		kwork[7] = key[0];
		kwork[8] = key[57];
		kwork[9] = key[49];
		kwork[10] = key[41];
		kwork[11] = key[33];
		kwork[12] = key[25];
		kwork[13] = key[17];
		kwork[14] = key[9];
		kwork[15] = key[1];
		kwork[16] = key[58];
		kwork[17] = key[50];
		kwork[18] = key[42];
		kwork[19] = key[34];
		kwork[20] = key[26];
		kwork[21] = key[18];
		kwork[22] = key[10];
		kwork[23] = key[2];
		kwork[24] = key[59];
		kwork[25] = key[51];
		kwork[26] = key[43];
		kwork[27] = key[35];
		kwork[28] = key[62];
		kwork[29] = key[54];
		kwork[30] = key[46];
		kwork[31] = key[38];
		kwork[32] = key[30];
		kwork[33] = key[22];
		kwork[34] = key[14];
		kwork[35] = key[6];
		kwork[36] = key[61];
		kwork[37] = key[53];
		kwork[38] = key[45];
		kwork[39] = key[37];
		kwork[40] = key[29];
		kwork[41] = key[21];
		kwork[42] = key[13];
		kwork[43] = key[5];
		kwork[44] = key[60];
		kwork[45] = key[52];
		kwork[46] = key[44];
		kwork[47] = key[36];
		kwork[48] = key[28];
		kwork[49] = key[20];
		kwork[50] = key[12];
		kwork[51] = key[4];
		kwork[52] = key[27];
		kwork[53] = key[19];
		kwork[54] = key[11];
		kwork[55] = key[3];
		/* 开始计算子键 */
		byte nbrofshift;
		byte temp1, temp2;
		for (int iter = 0; iter < 16; iter++) {
			nbrofshift = shift[iter];
			for (int i = 0; i < (int) nbrofshift; i++) {
				temp1 = kwork[0];
				temp2 = kwork[28];
				for (int k = 0; k < 27; k++) {
					kwork[k] = kwork[k + 1];
					kwork[k + 28] = kwork[k + 29];
				}
				kwork[27] = temp1;
				kwork[55] = temp2;
			}
			/* Permute kwork - PC2 */
			kn[0] = kwork[13];
			kn[1] = kwork[16];
			kn[2] = kwork[10];
			kn[3] = kwork[23];
			kn[4] = kwork[0];
			kn[5] = kwork[4];
			kn[6] = kwork[2];
			kn[7] = kwork[27];
			kn[8] = kwork[14];
			kn[9] = kwork[5];
			kn[10] = kwork[20];
			kn[11] = kwork[9];
			kn[12] = kwork[22];
			kn[13] = kwork[18];
			kn[14] = kwork[11];
			kn[15] = kwork[3];
			kn[16] = kwork[25];
			kn[17] = kwork[7];
			kn[18] = kwork[15];
			kn[19] = kwork[6];
			kn[20] = kwork[26];
			kn[21] = kwork[19];
			kn[22] = kwork[12];
			kn[23] = kwork[1];
			kn[24] = kwork[40];
			kn[25] = kwork[51];
			kn[26] = kwork[30];
			kn[27] = kwork[36];
			kn[28] = kwork[46];
			kn[29] = kwork[54];
			kn[30] = kwork[29];
			kn[31] = kwork[39];
			kn[32] = kwork[50];
			kn[33] = kwork[44];
			kn[34] = kwork[32];
			kn[35] = kwork[47];
			kn[36] = kwork[43];
			kn[37] = kwork[48];
			kn[38] = kwork[38];
			kn[39] = kwork[55];
			kn[40] = kwork[33];
			kn[41] = kwork[52];
			kn[42] = kwork[45];
			kn[43] = kwork[41];
			kn[44] = kwork[49];
			kn[45] = kwork[35];
			kn[46] = kwork[28];
			kn[47] = kwork[31];
			switch (iter) {
			case 0:
				for (int k = 0; k < 48; k++) {
					k1[k] = kn[k];
				}
				break;
			case 1:
				for (int k = 0; k < 48; k++) {
					k2[k] = kn[k];
				}
				break;
			case 2:
				for (int k = 0; k < 48; k++) {
					k3[k] = kn[k];
				}
				break;
			case 3:
				for (int k = 0; k < 48; k++) {
					k4[k] = kn[k];
				}
				break;
			case 4:
				for (int k = 0; k < 48; k++) {
					k5[k] = kn[k];
				}
				break;
			case 5:
				for (int k = 0; k < 48; k++) {
					k6[k] = kn[k];
				}
				break;
			case 6:
				for (int k = 0; k < 48; k++) {
					k7[k] = kn[k];
				}
				break;
			case 7:
				for (int k = 0; k < 48; k++) {
					k8[k] = kn[k];
				}
				break;
			case 8:
				for (int k = 0; k < 48; k++) {
					k9[k] = kn[k];
				}
				break;
			case 9:
				for (int k = 0; k < 48; k++) {
					k10[k] = kn[k];
				}
				break;
			case 10:
				for (int k = 0; k < 48; k++) {
					k11[k] = kn[k];
				}
				break;
			case 11:
				for (int k = 0; k < 48; k++) {
					k12[k] = kn[k];
				}
				break;
			case 12:
				for (int k = 0; k < 48; k++) {
					k13[k] = kn[k];
				}
				break;
			case 13:
				for (int k = 0; k < 48; k++) {
					k14[k] = kn[k];
				}
				break;
			case 14:
				for (int k = 0; k < 48; k++) {
					k15[k] = kn[k];
				}
				break;
			case 15:
				for (int k = 0; k < 48; k++) {
					k16[k] = kn[k];
				}
				break;
			}
		}
	}
}

程序解读

1.DES算法的入口参数包括Key、Data和Mode。其中,Key为8字节共64位,是DES算法的工作密钥;Data也为8字节共64位,是要被加密或被解密的数据;Mode为DES的工作方式,有两种:加密和解密。

2.下面的一个构造方法主要是将文件放在缓存区内。这是一个静态的方法,可以对这个方法进行调用,找到文件的存放路径。

private static int Channel_Buf(FileChannel channel,ByteBuffer buf)

3.DES算法的工作流程:如果Mode为加密,则用Key把数据Data进行加密,生成Data的密码形式(64位)作为DES的输出结果;如果Mode为解密,则用Key把密码形式的数据Data解密,还原为Data的明码形式(64位)作为DES的输出结果。


评论关闭
评论 还能输入200
评论关闭
评论 还能输入200
资料加载中...
已关注 , 取消