3DES加解密算法


在日常設計及開發中,為確保數據傳輸和數據存儲的安全,可通過特定的算法,將數據明文加密成復雜的密文。目前主流加密手段大致可分為單向加密和雙向加密。

 

單向加密:通過對數據進行摘要計算生成密文,密文不可逆推還原。算法代表:Base64,MD5,SHA;

 

雙向加密:與單向加密相反,可以把密文逆推還原成明文,雙向加密又分為對稱加密和非對稱加密。

對稱加密:指數據使用者必須擁有相同的密鑰才可以進行加密解密,就像彼此約定的一串暗號。算法代表:DES,3DES,AES,IDEA,RC4,RC5;

非對稱加密:相對對稱加密而言,無需擁有同一組密鑰,非對稱加密是一種“信息公開的密鑰交換協議”。非對稱加密需要公開密鑰和私有密鑰兩組密鑰,公開密鑰和私有密鑰是配對起來的,也就是說使用公開密鑰進行數據加密,只有對應的私有密鑰才能解密。這兩個密鑰是數學相關,用某用戶密鑰加密后的密文,只能使用該用戶的加密密鑰才能解密。如果知道了其中一個,並不能計算出另外一個。因此如果公開了一對密鑰中的一個,並不會危害到另外一個密鑰性質。這里把公開的密鑰為公鑰,不公開的密鑰為私鑰。算法代表:RSA,DSA。

 

======================================================

3DES算法

3DES是三重數據加密,且可以逆推的一種算法方案。但由於3DES的算法是公開的,所以算法本身沒有密鑰可言,主要依靠唯一密鑰來確保數據加解密的安全。到目前為止,仍沒有人能破解3DES。

 

3DES(或稱為Triple DES)是三重數據加密算法(TDEA,Triple Data Encryption Algorithm)塊密碼的通稱。它相當於是對每個數據塊應用三次DES加密算法。由於計算機運算能力的增強,原版DES密碼的密鑰長度變得容易被暴力破解;3DES即是設計用來提供一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼算法

3DES加解密工具類

  1 package tqx.demo;
  2 
  3 
  4 
  5 import java.net.URLDecoder;
  6 import java.net.URLEncoder;
  7 import java.security.Key;
  8 
  9 import javax.crypto.Cipher;
 10 import javax.crypto.SecretKeyFactory;
 11 import javax.crypto.spec.DESedeKeySpec;
 12 import javax.crypto.spec.IvParameterSpec;
 13 
 14 import com.alibaba.fastjson.JSONObject;
 15 
 16 /**
 17  * 3DES加密工具類
 18  * 
 19  */
 20 public class INITDES3Util {
 21     // 密鑰
 22     private  static String SECRETKEY = "INbSvyvOTkSkcRNSc8HpHIat";
 23     // 向量
 24     private  static String IV = "drS66rwt";
 25     // 加解密統一使用的編碼方式
 26     private final static String encoding = "utf-8";
 27     
 28     public  INITDES3Util(String s,String v ){
 29         this.SECRETKEY=s;
 30         this.IV=v;
 31     }
 32 
 33     /**
 34      * 3DES加密
 35      * 
 36      * @param plainText
 37      *            普通文本
 38      * @return
 39      */
 40     public  String encrypt(String plainText) throws Exception {
 41         Key deskey = null;
 42         DESedeKeySpec spec = new DESedeKeySpec(SECRETKEY.getBytes());
 43         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
 44         deskey = keyfactory.generateSecret(spec);
 45 
 46         Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
 47         IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
 48         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
 49         byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
 50         return Base64.encode(encryptData);
 51     }
 52 
 53     /**
 54      * 3DES解密
 55      * 
 56      * @param encryptText
 57      *            加密文本
 58      * @return
 59      */
 60     public  String decrypt(String encryptText) throws Exception {
 61         Key deskey = null;
 62         DESedeKeySpec spec = new DESedeKeySpec(SECRETKEY.getBytes());
 63         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
 64         deskey = keyfactory.generateSecret(spec);
 65         Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
 66         IvParameterSpec ips = new IvParameterSpec(IV.getBytes());
 67         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
 68 
 69         byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
 70 
 71         return new String(decryptData, encoding);
 72     }
 73 
 74     /**
 75      * 3DES加密
 76      * 
 77      * @param secretKey
 78      *            秘鑰
 79      * @param iv
 80      *            偏移向量
 81      * @param plainText
 82      *            普通文本
 83      * @return
 84      * @throws Exception
 85      */
 86     public static String encryptString(String secretKey, String iv,
 87             String plainText) throws Exception {
 88         Key deskey = null;
 89         DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
 90         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
 91         deskey = keyfactory.generateSecret(spec);
 92 
 93         Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
 94         IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
 95         cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
 96         byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
 97         return Base64.encode(encryptData);
 98     }
 99 
100     /**
101      * 3DES解密
102      * 
103      * @param secretKey
104      *            秘鑰
105      * @param iv
106      *            偏移向量
107      * @param encryptText
108      *            密文
109      * @return
110      * @throws Exception
111      */
112     public static String decryptString(String secretKey, String iv,
113             String encryptText) throws Exception {
114         Key deskey = null;
115         DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
116         SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
117         deskey = keyfactory.generateSecret(spec);
118         Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
119         IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
120         cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
121 
122         byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
123 
124         return new String(decryptData, encoding);
125     }
126 
127     /**
128      * 3DES解碼后解密
129      * 
130      * @param secretKey
131      *            秘鑰
132      * @param iv
133      *            偏移向量
134      * @param encryptText
135      *            密文
136      * @return
137      * @throws Exception
138      */
139     public static String decryptStringURLDecoder(String secretKey, String iv,
140             String encryptText) throws Exception {
141         String retJsonStr = decryptString(secretKey, iv,
142                 URLDecoder.decode(encryptText));
143         return retJsonStr;
144     }
145 
146     /**
147      * URLEncoder編碼加密信息
148      * 
149      * @param secretKey
150      * @param iv
151      * @param plainText
152      * @return
153      * @throws Exception
154      */
155     public static String encryptStringURLEncoder(String secretKey, String iv,
156             String plainText) throws Exception {
157         String base64Str = encryptString(secretKey, iv, plainText);
158         return URLEncoder.encode(base64Str);
159     }
160     
161 
162     public static void main(String[] args) throws Exception {
163         String result="";
164         INITDES3Util desSource=new INITDES3Util("INbSvyvOTkSkcRNSc8HpHIat","drS66rwt");
165         //JSONObject outData = new JSONObject();
166         //JSONObject resultOutData = new JSONObject();
167         String outputStr="123456";
168         String para=desSource.encrypt(outputStr);//加密json串
169         System.out.println(para);
170         String decryptString = INITDES3Util.encryptString("INbSvyvOTkSkcRNSc8HpHIat","drS66rwt", "sysadmin");
171         System.out.println(decryptString);
172         
173     }
174 
175 }

URLDecoder類包含一個decode(String s,String charcter)靜態方法,它可以將看上去亂碼的特殊字符串轉換成普通字符串
 URLEncoder類包含一個encode(String s,String charcter)靜態方法,它可以將普通字符串轉換成application/x-www-form-urlencoded MIME字符串

base64

  1 package tqx.demo;
  2 
  3 
  4 import java.io.ByteArrayOutputStream;
  5 import java.io.IOException;
  6 import java.io.OutputStream;
  7 
  8 /**
  9  * Base64編碼工具類
 10  * 
 11  */
 12 public class Base64 {
 13     private static final char[] legalChars = 
 14 
 15 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 16             .toCharArray();
 17 
 18     public static String encode(byte[] data) {
 19         int start = 0;
 20         int len = data.length;
 21         StringBuffer buf = new StringBuffer(data.length * 3 / 
 22 
 23 2);
 24 
 25         int end = len - 3;
 26         int i = start;
 27         int n = 0;
 28 
 29         while (i <= end) {
 30             int d = ((((int) data[i]) & 0x0ff) << 16)
 31                     | ((((int) data[i + 1]) & 0x0ff) 
 32 
 33 << 8)
 34                     | (((int) data[i + 2]) & 0x0ff);
 35 
 36             buf.append(legalChars[(d >> 18) & 63]);
 37             buf.append(legalChars[(d >> 12) & 63]);
 38             buf.append(legalChars[(d >> 6) & 63]);
 39             buf.append(legalChars[d & 63]);
 40 
 41             i += 3;
 42 
 43             if (n++ >= 14) {
 44                 n = 0;
 45                 buf.append(" ");
 46             }
 47         }
 48 
 49         if (i == start + len - 2) {
 50             int d = ((((int) data[i]) & 0x0ff) << 16)
 51                     | ((((int) data[i + 1]) & 255) 
 52 
 53 << 8);
 54 
 55             buf.append(legalChars[(d >> 18) & 63]);
 56             buf.append(legalChars[(d >> 12) & 63]);
 57             buf.append(legalChars[(d >> 6) & 63]);
 58             buf.append("=");
 59         } else if (i == start + len - 1) {
 60             int d = (((int) data[i]) & 0x0ff) << 16;
 61 
 62             buf.append(legalChars[(d >> 18) & 63]);
 63             buf.append(legalChars[(d >> 12) & 63]);
 64             buf.append("==");
 65         }
 66 
 67         return buf.toString();
 68     }
 69 
 70     private static int decode(char c) {
 71         if (c >= 'A' && c <= 'Z')
 72             return ((int) c) - 65;
 73         else if (c >= 'a' && c <= 'z')
 74             return ((int) c) - 97 + 26;
 75         else if (c >= '0' && c <= '9')
 76             return ((int) c) - 48 + 26 + 26;
 77         else
 78             switch (c) {
 79             case '+':
 80                 return 62;
 81             case '/':
 82                 return 63;
 83             case '=':
 84                 return 0;
 85             default:
 86                 throw new RuntimeException("unexpectedcode: " + c);
 87             }
 88     }
 89 
 90     /**
 91      * Decodes the given Base64 encoded String to a new byte array. 
 92 
 93 The byte
 94      * array holding the decoded data is returned.
 95      */
 96 
 97     public static byte[] decode(String s) {
 98 
 99         ByteArrayOutputStream bos = new ByteArrayOutputStream();
100         try {
101             decode(s, bos);
102         } catch (IOException e) {
103             throw new RuntimeException();
104         }
105         byte[] decodedBytes = bos.toByteArray();
106         try {
107             bos.close();
108             bos = null;
109         } catch (IOException ex) {
110             System.err.println("Error while decoding BASE64:" + ex.toString());
111         }
112         return decodedBytes;
113     }
114 
115     private static void decode(String s, OutputStream os) throws 
116 
117 IOException {
118         int i = 0;
119 
120         int len = s.length();
121 
122         while (true) {
123             while (i < len && s.charAt(i) <= ' ')
124                 i++;
125 
126             if (i == len)
127                 break;
128 
129             int tri = (decode(s.charAt(i)) << 18)
130                     + (decode(s.charAt(i + 1)) << 
131 
132 12)
133                     + (decode(s.charAt(i + 2)) << 6)
134                     + (decode(s.charAt(i + 3)));
135 
136             os.write((tri >> 16) & 255);
137             if (s.charAt(i + 2) == '=')
138                 break;
139             os.write((tri >> 8) & 255);
140             if (s.charAt(i + 3) == '=')
141                 break;
142             os.write(tri & 255);
143 
144             i += 4;
145         }
146     }
147 }

測試

package tqx.demo;

public class Demo3 {

    public static void main(String[] args) throws Exception {
        String encryptStringURLEncoder = INITDES3Util.encryptStringURLEncoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", "123456");
        System.out.println("電話加密后:"+encryptStringURLEncoder);
        String decryptStringURLDecoder = INITDES3Util.decryptStringURLDecoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", encryptStringURLEncoder);
        System.out.println("電話解密后:"+decryptStringURLDecoder);
        String encryptStringURLEncoder1 = INITDES3Util.encryptStringURLEncoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", "tqx");
        System.out.println("24加密后:"+encryptStringURLEncoder1);
        String decryptStringURLDecoder1 = INITDES3Util.decryptStringURLDecoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", encryptStringURLEncoder1);
        System.out.println("24解密后:"+decryptStringURLDecoder1);
        String encryptStringURLEncoder2 = INITDES3Util.encryptStringURLEncoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", "512501197203035172");
        System.out.println("身份證號加密后:"+encryptStringURLEncoder2);
        String decryptStringURLDecoder2 = INITDES3Util.decryptStringURLDecoder("INbSvyvOTkSkcRNSc8HpHIat", "drS66rwt", encryptStringURLEncoder2);
        System.out.println("身份證號解密后:"+decryptStringURLDecoder2);
        byte[] decode = Base64.decode("12345600");
        System.out.println(decode.toString());

    }

}

針對特殊字符的處理   '+'

str.toString()).replaceAll("\\+", "%2B");

// 密鑰24位
private static String SECRETKEY = "INbSvyvOTkSkcRNSc8HpHIat";
// 向量6位
private static String IV = "drS66rwt";

生成方法

package tqx.demo;

import java.util.Random;

public class RandomUtil {
    public static final String ALLCHAR = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String LETTERCHAR = "abcdefghijkllmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static final String NUMBERCHAR = "0123456789";

    /** 
     * 返回一個定長的帶因子的固定的隨機字符串(只包含大小寫字母、數字)
     *  
     * @param length 
     *            隨機字符串長度 
     * @return 隨機字符串 
     */
    public static String generateStringByKey(int length, int channel) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random(channel);
        for (int i = 0; i < length; i++) {
            sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
        }
        return sb.toString();
    }

    /** 
     * 返回一個定長的隨機字符串(只包含大小寫字母、數字)
     *  
     * @param length 
     *            隨機字符串長度 
     * @return 隨機字符串 
     */
    public static String generateString(int length) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(ALLCHAR.charAt(random.nextInt(ALLCHAR.length())));
        }
        return sb.toString();
    }

    /** 
     * 返回一個定長的隨機純字母字符串(只包含大小寫字母) 
     *  
     * @param length 
     *            隨機字符串長度 
     * @return 隨機字符串 
     */
    public static String generateMixString(int length) {
        StringBuffer sb = new StringBuffer();
        Random random = new Random();
        for (int i = 0; i < length; i++) {
            sb.append(ALLCHAR.charAt(random.nextInt(LETTERCHAR.length())));
        }
        return sb.toString();
    }

    /** 
     * 返回一個定長的隨機純大寫字母字符串(只包含大小寫字母) 
     *  
     * @param length 
     *            隨機字符串長度 
     * @return 隨機字符串 
     */
    public static String generateLowerString(int length) {
        return generateMixString(length).toLowerCase();
    }

    /** 
     * 返回一個定長的隨機純小寫字母字符串(只包含大小寫字母) 
     *  
     * @param length 
     *            隨機字符串長度 
     * @return 隨機字符串 
     */
    public static String generateUpperString(int length) {
        return generateMixString(length).toUpperCase();
    }

    /** 
     * 生成一個定長的純0字符串 
     *  
     * @param length 
     *            字符串長度 
     * @return 純0字符串 
     */
    public static String generateZeroString(int length) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            sb.append('0');
        }
        return sb.toString();
    }

    /** 
     * 根據數字生成一個定長的字符串,長度不夠前面補0 
     *  
     * @param num 
     *            數字 
     * @param fixdlenth 
     *            字符串長度 
     * @return 定長的字符串 
     */
    public static String toFixdLengthString(long num, int fixdlenth) {
        StringBuffer sb = new StringBuffer();
        String strNum = String.valueOf(num);
        if (fixdlenth - strNum.length() >= 0) {
            sb.append(generateZeroString(fixdlenth - strNum.length()));
        } else {
            throw new RuntimeException("將數字" + num + "轉化為長度為" + fixdlenth + "的字符串發生異常!");
        }
        sb.append(strNum);
        return sb.toString();
    }

    /** 
     * 每次生成的len位數都不相同 
     *  
     * @param param 
     * @return 定長的數字 
     */
    public static int getNotSimple(int[] param, int len) {
        Random rand = new Random();
        for (int i = param.length; i > 1; i--) {
            int index = rand.nextInt(i);
            int tmp = param[index];
            param[index] = param[i - 1];
            param[i - 1] = tmp;
        }
        int result = 0;
        for (int i = 0; i < len; i++) {
            result = result * 10 + param[i];
        }
        return result;
    }

    public static void main(String[] args) {
        int channel = 555555;// 測試因子比生產因子少1
        System.out.println("返回一個定長的帶因子的固定的隨機字符串(只包含大小寫字母、數字):" + generateStringByKey(24, channel));
        System.out.println("返回一個定長的隨機字符串(只包含大小寫字母、數字):" + generateString(24));
        System.out.println("返回一個定長的隨機純字母字符串(只包含大小寫字母):" + generateMixString(6));
        System.out.println("返回一個定長的隨機純大寫字母字符串(只包含大小寫字母):" + generateLowerString(6));
        System.out.println("返回一個定長的隨機純小寫字母字符串(只包含大小寫字母):" + generateUpperString(6));
        System.out.println("生成一個定長的純0字符串:" + generateZeroString(6));
        System.out.println("根據數字生成一個定長的字符串,長度不夠前面補0:" + toFixdLengthString(123, 6));
        int[] in = { 1, 2, 3, 4, 5, 6, 7 };
        System.out.println("每次生成的len位數都不相同:" + getNotSimple(in, 3));
    }

}
返回一個定長的帶因子的固定的隨機字符串(只包含大小寫字母、數字):MaigTil28hVETWTssFHGtYDx
返回一個定長的隨機字符串(只包含大小寫字母、數字):6sBcIpRocWTyBLiKvyNAQ0Sd
返回一個定長的隨機純字母字符串(只包含大小寫字母):LLQMLv
返回一個定長的隨機純大寫字母字符串(只包含大小寫字母):mp6d7s
返回一個定長的隨機純小寫字母字符串(只包含大小寫字母):MWYWIF
生成一個定長的純0字符串:000000
根據數字生成一個定長的字符串,長度不夠前面補0:000123
每次生成的len位數都不相同:651

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM