• 加密与编码


    Java加密的常用的加密算法类型有三种

    1单向加密:也就是不可逆的加密,例如MD5,SHA,HMAC

    2对称加密:也就是加密方和解密方利用同一个秘钥对数据进行加密和解密,例如DES,PBE等等

    3非对称加密:非对称加密分为公钥和秘钥,二者是非对称的,例如用私钥加密的内容需要使用公钥来解密,使用公钥加密的内容需要用私钥来解密,DSA,RSA...

    而keyGenerator,KeyPairGenerator,SecretKeyFactory的三种使用方法刚好和这三种加密算法类型对上

    keyGenerator:秘钥生成器,也就是更具算法类型随机生成一个秘钥,例如HMAC,所以这个大部分用在非可逆的算法中

    SecretKeyFactory:秘密秘钥工厂,言外之意就是需要根据一个秘密(password)去生成一个秘钥,例如DES,PBE,所以大部分使用在对称加密中

    KeyPairGenerator:秘钥对生成器,也就是可以生成一对秘钥,也就是公钥和私钥,所以大部分使用在非对称加密中

    SecretKeyFactory类

    SecretKeyFactory表示秘密密钥的工厂。类声明:public class SecretKeyFactory extends Object

    例子:

    try {  
        // 获取密钥工厂类对象  
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");  
        byte[] DESkey = "abcdefghijk".getBytes("UTF-8");// 设置密钥  
        DESKeySpec keySpec = new DESKeySpec(DESkey);// 设置密钥参数  
        Key key = keyFactory.generateSecret(keySpec);// 得到密钥对象  
    } catch (Exception e) {  
        e.printStackTrace();  
    }  

    详见:https://blog.csdn.net/u010142437/article/details/17767809

    对称加密算法-DES以及DESede算法

      对称加密算法就是能将数据加解密。加密的时候用密钥对数据进行加密,解密的时候使用同样的密钥对数据进行解密。

    1、des算法

      1 package com.ca.test;
      2 import java.security.Key;
      3 import javax.crypto.Cipher;
      4 import javax.crypto.KeyGenerator;
      5 import javax.crypto.SecretKey;
      6 import javax.crypto.SecretKeyFactory;
      7 import javax.crypto.spec.DESKeySpec;
      8 import org.apache.commons.codec.binary.Base64;
      9 /**
     10  * DES对称加密算法
     11  * @author kongqz
     12  * */
     13 public class DESCoder {
     14     /**
     15      * 密钥算法
     16      * java支持56位密钥,bouncycastle支持64位
     17      * */
     18     public static final String KEY_ALGORITHM="DES";
     19     
     20     /**
     21      * 加密/解密算法/工作模式/填充方式
     22      * */
     23     public static final String CIPHER_ALGORITHM="DES/ECB/PKCS5Padding";
     24     
     25     /**
     26      * 
     27      * 生成密钥,java6只支持56位密钥,bouncycastle支持64位密钥
     28      * @return byte[] 二进制密钥
     29      * */
     30     public static byte[] initkey() throws Exception{
     31         
     32         //实例化密钥生成器
     33         KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM);
     34         //初始化密钥生成器
     35         kg.init(56);
     36         //生成密钥
     37         SecretKey secretKey=kg.generateKey();
     38         //获取二进制密钥编码形式
     39         return secretKey.getEncoded();
     40     }
     41     /**
     42      * 转换密钥
     43      * @param key 二进制密钥
     44      * @return Key 密钥
     45      * */
     46     public static Key toKey(byte[] key) throws Exception{
     47         //实例化Des密钥
     48         DESKeySpec dks=new DESKeySpec(key);
     49         //实例化密钥工厂
     50         SecretKeyFactory keyFactory=SecretKeyFactory.getInstance(KEY_ALGORITHM);
     51         //生成密钥
     52         SecretKey secretKey=keyFactory.generateSecret(dks);
     53         return secretKey;
     54     }
     55     
     56     /**
     57      * 加密数据
     58      * @param data 待加密数据
     59      * @param key 密钥
     60      * @return byte[] 加密后的数据
     61      * */
     62     public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
     63         //还原密钥
     64         Key k=toKey(key);
     65         //实例化
     66         Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
     67         //初始化,设置为加密模式
     68         cipher.init(Cipher.ENCRYPT_MODE, k);
     69         //执行操作
     70         return cipher.doFinal(data);
     71     }
     72     /**
     73      * 解密数据
     74      * @param data 待解密数据
     75      * @param key 密钥
     76      * @return byte[] 解密后的数据
     77      * */
     78     public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
     79         //欢迎密钥
     80         Key k =toKey(key);
     81         //实例化
     82         Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
     83         //初始化,设置为解密模式
     84         cipher.init(Cipher.DECRYPT_MODE, k);
     85         //执行操作
     86         return cipher.doFinal(data);
     87     }
     88     /**
     89      * @param args
     90      * @throws Exception 
     91      */
     92     public static void main(String[] args) throws Exception {
     93         String str="DES";
     94         System.out.println("原文:"+str);
     95         //初始化密钥
     96         byte[] key=DESCoder.initkey();
     97         System.out.println("密钥:"+Base64.encodeBase64String(key));
     98         //加密数据
     99         byte[] data=DESCoder.encrypt(str.getBytes(), key);
    100         System.out.println("加密后:"+Base64.encodeBase64String(data));
    101         //解密数据
    102         data=DESCoder.decrypt(data, key);
    103         System.out.println("解密后:"+new String(data));
    104     }
    105 }
    106 控制台输出结果:
    107 原文:DES
    108 密钥:ocewbYVbtmE=
    109 加密后:w6KsVSkLV3Q=
    110 解密后:DES
    View Code

    2、desede算法演示

      1 package com.ca.test;
      2 import java.security.Key;
      3 import javax.crypto.Cipher;
      4 import javax.crypto.KeyGenerator;
      5 import javax.crypto.SecretKey;
      6 import javax.crypto.SecretKeyFactory;
      7 import javax.crypto.spec.DESedeKeySpec;
      8 import org.apache.commons.codec.binary.Base64;
      9 /**
     10  * DESede对称加密算法演示
     11  * @author kongqz
     12  * */
     13 public class DESedeCoder {
     14     /**
     15      * 密钥算法
     16      * */
     17     public static final String KEY_ALGORITHM="DESede";
     18     
     19     /**
     20      * 加密/解密算法/工作模式/填充方式
     21      * */
     22     public static final String CIPHER_ALGORITHM="DESede/ECB/PKCS5Padding";
     23     
     24     /**
     25      * 
     26      * 生成密钥
     27      * @return byte[] 二进制密钥
     28      * */
     29     public static byte[] initkey() throws Exception{
     30         
     31         //实例化密钥生成器
     32         KeyGenerator kg=KeyGenerator.getInstance(KEY_ALGORITHM);
     33         //初始化密钥生成器
     34         kg.init(168);
     35         //生成密钥
     36         SecretKey secretKey=kg.generateKey();
     37         //获取二进制密钥编码形式
     38         return secretKey.getEncoded();
     39     }
     40     /**
     41      * 转换密钥
     42      * @param key 二进制密钥
     43      * @return Key 密钥
     44      * */
     45     public static Key toKey(byte[] key) throws Exception{
     46         //实例化Des密钥
     47         DESedeKeySpec dks=new DESedeKeySpec(key);
     48         //实例化密钥工厂
     49         SecretKeyFactory keyFactory=SecretKeyFactory.getInstance(KEY_ALGORITHM);
     50         //生成密钥
     51         SecretKey secretKey=keyFactory.generateSecret(dks);
     52         return secretKey;
     53     }
     54     
     55     /**
     56      * 加密数据
     57      * @param data 待加密数据
     58      * @param key 密钥
     59      * @return byte[] 加密后的数据
     60      * */
     61     public static byte[] encrypt(byte[] data,byte[] key) throws Exception{
     62         //还原密钥
     63         Key k=toKey(key);
     64         //实例化
     65         Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
     66         //初始化,设置为加密模式
     67         cipher.init(Cipher.ENCRYPT_MODE, k);
     68         //执行操作
     69         return cipher.doFinal(data);
     70     }
     71     /**
     72      * 解密数据
     73      * @param data 待解密数据
     74      * @param key 密钥
     75      * @return byte[] 解密后的数据
     76      * */
     77     public static byte[] decrypt(byte[] data,byte[] key) throws Exception{
     78         //欢迎密钥
     79         Key k =toKey(key);
     80         //实例化
     81         Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM);
     82         //初始化,设置为解密模式
     83         cipher.init(Cipher.DECRYPT_MODE, k);
     84         //执行操作
     85         return cipher.doFinal(data);
     86     }
     87     /**
     88      * 进行加解密的测试
     89      * @throws Exception 
     90      */
     91     public static void main(String[] args) throws Exception {
     92         String str="DESede";
     93         System.out.println("原文:/t"+str);
     94         //初始化密钥
     95         byte[] key=DESedeCoder.initkey();
     96         System.out.println("密钥:/t"+Base64.encodeBase64String(key));
     97         //加密数据
     98         byte[] data=DESedeCoder.encrypt(str.getBytes(), key);
     99         System.out.println("加密后:/t"+Base64.encodeBase64String(data));
    100         //解密数据
    101         data=DESedeCoder.decrypt(data, key);
    102         System.out.println("解密后:/t"+new String(data));
    103     }
    104 }
    105 控制台输出结果:
    106 原文:    DESede
    107 密钥:    BBDmwTjBsF7IwTIyGWt1bmFntRyUgMQL
    108 加密后:    FM/DsEv3KgM=
    109 解密后:    DESede
    View Code

    base64

    Base64是一种用64个字符来表示任意二进制数据的方法。

    原理:

    Base64的原理很简单,首先,准备一个包含64个字符的数组:

    ['A', 'B', 'C', ... 'a', 'b', 'c', ... '0', '1', ... '+', '/']
    

    然后,对二进制数据进行处理,每3个字节一组,一共是3x8=24bit,划为4组,每组正好6个bit:

    base64-encode

    这样我们得到4个数字作为索引,然后查表,获得相应的4个字符,就是编码后的字符串。

    所以,Base64编码会把3字节的二进制数据编码为4字节的文本数据,长度增加33%,好处是编码后的文本数据可以在邮件正文、网页等直接显示。

    如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?Base64用x00字节在末尾补足后,再在编码的末尾加上1个或2个=号,表示补了多少字节,解码的时候,会自动去掉。

    使用:Base64是一种任意二进制到文本字符串的编码方法,常用于在URL、Cookie、网页中传输少量二进制数据

    java中使用:

    1 import java.util.Base64;
    2 对于标准的Base64:
    3 加密为字符串使用Base64.getEncoder().encodeToString();
    4 加密为字节数组使用Base64.getEncoder().encode();
    5 解密使用Base64.getDecoder().decode();
    6 对于URL安全或MIME的Base64,只需将上述getEncoder()getDecoder()更换为getUrlEncoder()getUrlDecoder()
    7 或getMimeEncoder()和getMimeDecoder()即可。

    URLEncoder

    客户端在进行网页请求的时候,网址中可能会包含非ASCII码形式的内容,比如中文。

    而直接把中文放到网址中请求是不允许的,所以需要用URLEncoder编码地址,

    将网址中的非ASCII码内容转换成可以传输的字符

    不会被编码的内容

    1.大写字母A-Z

    2.小写字母a-z

    3.数字 0-9

    4.标点符 - _ . ! ~ * ' (和 ,)

    编码原理

    1、将需要转换的内容(ASCII码形式之外的内容),用十六进制表示法转换出来,并在之前加上%开头

    eg:  0x9c  URLEncoder --> %9c

    2、内容中的空格‘ ’ ,全部用+代替

    3、注:与Hex不同,Hex是将所有的字符转换为16进制表示,而URLEncoder是将ASCII码集之外的转换为%加上相应的16进制,而ASCII码集内的字符不进行处理

    应用场景

    1、所有的GET请求

    2、网址中有中文等情况

    3、POST请求,所有的Key和Value在提交之前都要经过URLEncoder

    示例代码:

    try {
        String a = URLEncoder.encode("a", "UTF-8");
        Log.i("encode","a 进行URLEncoder编码后-->"+a );
        String b = URLEncoder.encode("a中", "UTF-8");
        Log.i("encode","a中 进行URLEncoder编码后-->"+b );
    
        String decode = nURLDecoder.decode("a%E4%B8%AD", "UTF-8");
        Log.i("encode","a%E4%B8%AD 进行URLDecoder解码后-->"+decode);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    运行结果:

    10-17 07:33:14.357 1012-1012/com.xqx.encrypsthow I/encode﹕ a 进行URLEncoder编码后-->a
    10-17 07:33:14.367 1012-1012/com.xqx.encrypsthow I/encode﹕ a中 进行URLEncoder编码后-->a%E4%B8%AD
    10-17 07:33:14.377 1012-1012/com.xqx.encrypsthow I/encode﹕ a%E4%B8%AD 进行URLDecoder解码后-->a中

    可以看出 字符'a' 并没有编码  而 中文 '中' 进行了编码

    与URLEncoder编码对应的是URLDecoder解码 

    可以看出 "a中"--编码-->"a%E4%B8%AD"--解码-->"a中"

  • 相关阅读:
    【(高职专科组)第十一届蓝桥杯省模拟赛答案】给定一个数列,请问找出元素之间最大的元素距离。
    【(高职专科组)第十一届蓝桥杯省模拟赛答案】给定一个数列,请问数列中最长的递增序列有多长。
    POJ 2391 二分+最大流
    HDU 4529 状压dp
    NYOJ 747贪心+dp
    NYOJ 745 dp
    HDU 2686 / NYOJ 61 DP
    HDU 4313树形DP
    HDU 4303 树形DP
    POJ 2342 树形DP
  • 原文地址:https://www.cnblogs.com/soul-wonder/p/8892677.html
Copyright © 2020-2023  润新知