DES加密算法详解+java源码
先说客套话:数据加密算法(Data Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的**系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的。通常,自动取款机(Automated Teller Machine,ATM)都使用DEA。它出自IBM的研究工作,IBM也曾对它拥有几年的专利权,但是在1983年已到期后,处于公有范围中,允许在特定条件下可以免除专利使用费而使用。1977年被美国政府正式采纳。
基本流程如下图所示
初始换位称为IP变换
逆初始变换称为IP逆变换
首先我们要把64位的**变换成16个48位的子**,如下图
其中64位压缩成56位称为PC1变换,56位压缩成48位称为PC2变换
循环左移的位数用数组表示
public static Integer MOVE_TIMES[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1 };
接下来就是最主要的循环加密了
最后对R与subKey的F变换做详细解释:
R(32)位扩展成R‘(48)称为E变换。
由R’与子**K异或运算获得的值称为R‘’(48)
将R‘’(48)分为8块,每块6位,分别是:a0a1a2a3a4a5,按顺序进行S盒变换
S盒共有8个盒子,每个盒子为4*16的二维数组,对第j个盒子的查询方式为s[j][x][y],其中x为a0a5组合成十进制数,y为a1a2a3a4组合成十进制数
S盒变换结束后得到32位数,再进行32位换位变换,称为P变换,从而完成所有F变换
现在贴上Java Web的Structs2+Ajax版本的DES详细加密代码,注释应该算详细,不懂可以留言问,或者联系QQ:770415878
显示structs的配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>
<package name="default" namespace="/" extends="struts-default">
<!-- ***************** DES详细 ************************** -->
<!-- 获取子** -->
<action name="GetSubKey" class="CipherCode.DesAction" method="GetSubKey">
</action>
<!-- Next变换 -->
<action name="Next" class="CipherCode.DesAction" method="Next">
</action>
<!-- Ip变换 -->
<action name="GetIpTrans" class="CipherCode.DesAction" method="GetIpTrans">
</action>
<!-- Ip逆变换 -->
<action name="GetIp1Trans" class="CipherCode.DesAction" method="GetIp1Trans">
</action>
<!-- 自动生成** -->
<action name="GetKey" class="CipherCode.DesAction" method="GetKey">
</action>
</package>
</struts>
接着是action的java类
package CipherCode;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONObject;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DesAction extends ActionSupport {
/**
* 产生子**
*
* @return
*/
public String GetSubKey() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
String key = request.getParameter("key");
try {
key = DesDetail.HexToTwo(key);
Map<String, Object> resultMap = DesDetail.DesMakeSubKeys(key);
JSONObject json = JSONObject.fromObject(resultMap);
// 设置编码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// 写入到前台
response.getWriter().write(json.toString());
System.out.println(json);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* IP变换
*
* @return
*/
public String GetIpTrans() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
Map<String, Object> resultMap = new HashMap<String, Object>();
String plainText = request.getParameter("plainText");
try {
String str = DesDetail.HexToTwo(plainText);
str = DesDetail.DesIpTransform(str);
str = DesDetail.TwoToHex(str);
String l0 = "";
String r0 = "";
for (int i = 0; i < 8; i++) {
l0 = l0 + str.charAt(i);
}
for (int i = 8; i < 16; i++) {
r0 = r0 + str.charAt(i);
}
resultMap.put("l0", l0);
resultMap.put("r0", r0);
JSONObject json = JSONObject.fromObject(resultMap);
// 设置编码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// 写入到前台
response.getWriter().write(json.toString());
System.out.println(json);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* NEXT变换
*
* @return
*/
public String Next() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
Map<String, Object> resultMap = new HashMap<String, Object>();
String subKey = request.getParameter("subKey");
String l = request.getParameter("l");
String r = request.getParameter("r");
try {
resultMap.put("l", r);
l = DesDetail.HexToTwo(l);
r = DesDetail.HexToTwo(r);
subKey = DesDetail.HexToTwo(subKey);
r = DesDetail.Xor32(l, DesDetail.DesFTransform(r, subKey));
r = DesDetail.TwoToHex(r);
resultMap.put("r", r);
JSONObject json = JSONObject.fromObject(resultMap);
// 设置编码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// 写入到前台
response.getWriter().write(json.toString());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* IP逆变换
*
* @return
*/
public String GetIp1Trans() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
Map<String, Object> resultMap = new HashMap<String, Object>();
String r = request.getParameter("r");
String l = request.getParameter("l");
try {
String cipherText = r + l;
cipherText = DesDetail.HexToTwo(cipherText);
cipherText = DesDetail.DesIp1Transform(cipherText);
cipherText = DesDetail.TwoToHex(cipherText);
resultMap.put("cipherText", cipherText);
JSONObject json = JSONObject.fromObject(resultMap);
// 设置编码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// 写入到前台
response.getWriter().write(json.toString());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 自动获取**
*
* @return
*/
public String GetKey() {
HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
Map<String, Object> resultMap = new HashMap<String, Object>();
try {
String buf = new String("0123456789abcdef");
Random temp = new Random();
String key = new String("");
for (int i = 0; i < 16; i++) {
int k = temp.nextInt(16);
char kk = buf.charAt(k);
key = key + String.valueOf(kk);
}
resultMap.put("key", key);
JSONObject json = JSONObject.fromObject(resultMap);
// 设置编码
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
// 写入到前台
response.getWriter().write(json.toString());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
最后是实现各种DES变换的java类,包括有所有变换的变换表
package CipherCode;
import java.util.HashMap;
public abstract class DesDetail {
/* 初始置换表IP 64个 */
public static Integer IP_Table[] = { 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, 56, 48, 40, 32, 24, 16, 8, 0, 58, 50, 42, 34,
26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4, 62, 54, 46, 38, 30,
22, 14, 6 };
/* 逆初始置换表IP^-1 64个 */
public static Integer IP_1_Table[] = { 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, 32, 0, 40, 8, 48,
16, 56, 24 };
/* 扩充置换表E 48个 */
public static Integer E_Table[] = { 31, 0, 1, 2, 3, 4, 3, 4, 5, 6, 7, 8, 7,
8, 9, 10, 11, 12, 11, 12, 13, 14, 15, 16, 15, 16, 17, 18, 19, 20,
19, 20, 21, 22, 23, 24, 23, 24, 25, 26, 27, 28, 27, 28, 29, 30, 31,
0 };
/* 置换函数P 32个 */
public static Integer P_Table[] = { 15, 6, 19, 20, 28, 11, 27, 16, 0, 14,
22, 25, 4, 17, 30, 9, 1, 7, 23, 13, 31, 26, 2, 8, 18, 12, 29, 5,
21, 10, 3, 24 };
/* S盒 8*4*16 */
public static Integer S[][][] = /* 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 } },
/* 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 } },
/* 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 } },
/* 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 } },
/* 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 } },
/* 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 } },
/* 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 } },
/* 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 } } };
/* 置换选择1 56个 */
public static Integer PC_1[] = { 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41,
33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35,
62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 60,
52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 };
/* 置换选择2 48个 */
public static Integer PC_2[] = { 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 40, 51, 30, 36, 46, 54,
29, 39, 50, 44, 32, 46, 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28,
31 };
/* 对左移次数的规定 16 */
public static Integer MOVE_TIMES[] = { 1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2,
2, 2, 2, 1 };
/* 16进制转换 */
public static String Hex[] = { "0000", "0001", "0010", "0011", "0100",
"0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100",
"1101", "1110", "1111" };
/*
* 产生子**64,16*48
*/
public static HashMap<String, Object> DesMakeSubKeys(String key) {
HashMap<String, Object> subKey = new HashMap<String, Object>();
key = DesPc1Transform(key);/* PC1置换 */
for (Integer i = 0; i < 16; i++) {/* 16轮跌代,产生16个子** */
key = DesRol(key, MOVE_TIMES[i]);/* 循环左移 */
String str = "subKey" + i.toString();
subKey.put(str, TwoToHex(DesPc2Transform(key)));/* PC2置换,产生子** */
}
return subKey;
}
/*
* PC1变换
*/
public static String DesPc1Transform(String key) {
String temp = "";
for (int i = 0; i < 56; i++) {
temp = temp + key.charAt(PC_1[i]);
}
return temp;
}
/*
* PC2变换
*/
public static String DesPc2Transform(String key) {
String temp = "";
for (int i = 0; i < 48; i++) {
temp = temp + key.charAt(PC_2[i]);
}
return temp;
}
/*
* 循环左移
*/
public static String DesRol(String key, Integer time) {
String temp = "";
for (int i = 0; i < 28; i++) {
if (i < 28 - time) {
temp = temp + key.charAt(i + time);
} else {
temp = temp + key.charAt(time + i - 27);
}
}
for (int i = 28; i < 56; i++) {
if (i < 56 - time) {
temp = temp + key.charAt(i + time);
} else {
temp = temp + key.charAt(time + i - 28);
}
}
return temp;
}
/*
* public static String HexToTwo(String key) { String temp = ""; for (int i
* = 0; i < 16; i++) { temp = temp + Hex[key.charAt(i)-'0']; } return temp;
* }
*/
/*
* 16进制转2进制
*/
public static String HexToTwo(String hexString) {
if (hexString == null || hexString.length() % 2 != 0)
return null;
String bString = "", tmp;
for (int i = 0; i < hexString.length(); i++) {
tmp = "0000"
+ Integer.toBinaryString(Integer.parseInt(
hexString.substring(i, i + 1), 16));
bString += tmp.substring(tmp.length() - 4);
}
return bString;
}
/*
* 2进制转16进制
*/
public static String TwoToHex(String bString) {
if (bString == null || bString.equals("") || bString.length() % 8 != 0)
return null;
StringBuffer tmp = new StringBuffer();
int iTmp = 0;
for (int i = 0; i < bString.length(); i += 4) {
iTmp = 0;
for (int j = 0; j < 4; j++) {
iTmp += Integer.parseInt(bString.substring(i + j, i + j + 1)) << (4 - j - 1);
}
tmp.append(Integer.toHexString(iTmp));
}
return tmp.toString();
}
/*
* 2进制转10进制
*/
public static Integer TwoToInteger(String bString) {
Integer temp = 0;
if (bString.equals("00") || bString.equals("0000"))
temp = 0;
else if (bString.equals("01") || bString.equals("0001"))
temp = 1;
else if (bString.equals("10") || bString.equals("0010"))
temp = 2;
else if (bString.equals("11") || bString.equals("0011"))
temp = 3;
else if (bString.equals("0100"))
temp = 4;
else if (bString.equals("0101"))
temp = 5;
else if (bString.equals("0110"))
temp = 6;
else if (bString.equals("0111"))
temp = 7;
else if (bString.equals("1000"))
temp = 8;
else if (bString.equals("1001"))
temp = 9;
else if (bString.equals("1010"))
temp = 10;
else if (bString.equals("1011"))
temp = 11;
else if (bString.equals("1100"))
temp = 12;
else if (bString.equals("1101"))
temp = 13;
else if (bString.equals("1110"))
temp = 14;
else if (bString.equals("1111"))
temp = 15;
return temp;
}
/*
* IP变换
*/
public static String DesIpTransform(String key) {
String temp = "";
for (int i = 0; i < 64; i++) {
temp = temp + key.charAt(IP_Table[i]);
}
return temp;
}
/*
* IP逆变换
*/
public static String DesIp1Transform(String key) {
String temp = "";
for (int i = 0; i < 64; i++) {
temp = temp + key.charAt(IP_1_Table[i]);
}
return temp;
}
/*
* E变换
*/
public static String DesETransform(String key) {
String temp = "";
for (int i = 0; i < 48; i++) {
temp = temp + key.charAt(E_Table[i]);
}
return temp;
}
/*
* F变换
*/
public static String DesFTransform(String r, String subKey) {
String temp = "";
r = DesETransform(r);// 将r进行E变换
String key = Xor48(r, subKey);
for (int i = 0; i < 48; i++) {
if (i % 6 == 0) {
String k1 = "" + key.charAt(i);
k1 = k1 + key.charAt(i + 5);
String k2 = "";
for (int j = 1; j < 5; j++) {
k2 = k2 + key.charAt(i + j);
}
temp = temp + Hex[S[i / 6][TwoToInteger(k1)][TwoToInteger(k2)]];
}
}
temp = DesPTransform(temp);
return temp;
}
/*
* P变换
*/
public static String DesPTransform(String key) {
String temp = "";
for (int i = 0; i < 32; i++) {
temp = temp + key.charAt(P_Table[i]);
}
return temp;
}
/*
* 48位异或运算
*/
public static String Xor48(String key1, String key2) {
String temp = "";
for (int i = 0; i < 48; i++) {
if (key1.charAt(i) == key2.charAt(i)) {
temp = temp + "0";
} else {
temp = temp + "1";
}
}
return temp;
}
/*
* 32位异或运算
*/
public static String Xor32(String key1, String key2) {
String temp = "";
for (int i = 0; i < 32; i++) {
if (key1.charAt(i) == key2.charAt(i)) {
temp = temp + "0";
} else {
temp = temp + "1";
}
}
return temp;
}
}
转载于:https://www.cnblogs.com/Free-rein/archive/2013/06/06/3123063.html