zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    [硬件驱动_蓝牙]蓝牙Bluez的编程实现
    二分查找
    LeetCode-35.Search Insert Position
    LeetCode-34.Find First and Last Position of Element in Sorted Array
    LeetCode-704.Binary Search
    剑指offer-最小的k个数
    树的各种遍历
    LeetCode-912.Sort an Array
    排序
    LeetCode-209.Minimum Size Subarray Sum
  • 原文地址:https://www.cnblogs.com/xiaotang5051729/p/9881877.html
Copyright © 2011-2022 走看看