DES加密算法详解+java源码

先说客套话:数据加密算法(Data Encryption Algorithm,DEA)是一种对称加密算法,很可能是使用最广泛的**系统,特别是在保护金融数据的安全中,最初开发的DEA是嵌入硬件中的。通常,自动取款机(Automated Teller Machine,ATM)都使用DEA。它出自IBM的研究工作,IBM也曾对它拥有几年的专利权,但是在1983年已到期后,处于公有范围中,允许在特定条件下可以免除专利使用费而使用。1977年被美国*正式采纳。

 

基本流程如下图所示

初始换位称为IP变换

逆初始变换称为IP逆变换

DES加密算法详解+java源码

 

 

首先我们要把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 };

 

DES加密算法详解+java源码

 

接下来就是最主要的循环加密了

DES加密算法详解+java源码

最后对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变换

DES加密算法详解+java源码

 

现在贴上Java Web的Structs2+Ajax版本的DES详细加密代码,注释应该算详细,不懂可以留言问,或者联系QQ:770415878

显示structs的配置文件

DES加密算法详解+java源码DES加密算法详解+java源码
<?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>
structs.xml

接着是action的java类

DES加密算法详解+java源码DES加密算法详解+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;
    }

}
DesAction

最后是实现各种DES变换的java类,包括有所有变换的变换表

DES加密算法详解+java源码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;
    }

}
DesDetail

 

转载于:https://www.cnblogs.com/Free-rein/archive/2013/06/06/3123063.html