在日常设计及开发中,为确保数据传输和数据存储的安全,可通过特定的算法,将数据明文加密成复杂的密文。目前主流加密手段大致可分为单向加密和双向加密。

 

单向加密:通过对数据进行摘要计算生成密文,密文不可逆推还原。算法代表: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