• JDK自带方法实现AES对称加密


    请看代码。

      1 package jdbc.pro.lin;
      2 
      3 import java.security.InvalidAlgorithmParameterException;
      4 import java.security.InvalidKeyException;
      5 import java.security.NoSuchAlgorithmException;
      6 
      7 import javax.crypto.BadPaddingException;
      8 import javax.crypto.Cipher;
      9 import javax.crypto.IllegalBlockSizeException;
     10 import javax.crypto.KeyGenerator;
     11 import javax.crypto.NoSuchPaddingException;
     12 import javax.crypto.SecretKey;
     13 import javax.crypto.spec.IvParameterSpec;
     14 import javax.crypto.spec.SecretKeySpec;
     15 
     16 import org.apache.commons.codec.binary.Base64;
     17 
     18 public class MyAES {
     19     /**
     20      * 注意key和加密用到的字符串是不一样的 加密还要指定填充的加密模式和填充模式 AES密钥可以是128或者256,加密模式包括ECB, CBC等
     21      * ECB模式是分组的模式,CBC是分块加密后,每块与前一块的加密结果异或后再加密 第一块加密的明文是与IV变量进行异或
     22      */
     23     public static final String KEY_ALGORITHM = "AES";
     24     public static final String ECB_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
     25     public static final String CBC_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
     26     public static final String PLAIN_TEXT = "MANUTD is the greatest club in the world";
     27 
     28     /**
     29      * IV(Initialization Value)是一个初始值,对于CBC模式来说,它必须是随机选取并且需要保密的
     30      * 而且它的长度和密码分组相同(比如:对于AES 128为128位,即长度为16的byte类型数组)
     31      * 
     32      */
     33     public static final byte[] IVPARAMETERS = new byte[] { 1, 2, 3, 4, 5, 6, 7,
     34             8, 9, 10, 11, 12, 13, 14, 15, 16 };
     35 
     36     public static void main(String[] arg) {
     37         byte[] secretBytes = generateAESSecretKey();
     38         SecretKey key = restoreSecretKey(secretBytes);
     39         byte[] encodedText = AesEcbEncode(PLAIN_TEXT.getBytes(), key);
     40 
     41         System.out.println("AES ECB encoded with Base64: " + Base64.encodeBase64String(encodedText));
     42         System.out.println("AES ECB decoded: "
     43                 + AesEcbDecode(encodedText, key));
     44 
     45         
     46         
     47         encodedText = AesCbcEncode(PLAIN_TEXT.getBytes(), key, IVPARAMETERS);
     48         
     49         
     50         System.out.println("AES CBC encoded with Base64: " + Base64.encodeBase64String(encodedText));
     51         System.out.println("AES CBC decoded: "
     52                 + AesCbcDecode(encodedText, key,
     53                         IVPARAMETERS));
     54     }
     55 
     56     /**
     57      * 使用ECB模式进行加密。 加密过程三步走: 1. 传入算法,实例化一个加解密器 2. 传入加密模式和密钥,初始化一个加密器 3.
     58      * 调用doFinal方法加密
     59      * 
     60      * @param plainText
     61      * @return
     62      */
     63     public static byte[] AesEcbEncode(byte[] plainText, SecretKey key) {
     64 
     65         try {
     66 
     67             Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
     68             cipher.init(Cipher.ENCRYPT_MODE, key);
     69             return cipher.doFinal(plainText);
     70         } catch (NoSuchAlgorithmException | NoSuchPaddingException
     71                 | InvalidKeyException | IllegalBlockSizeException
     72                 | BadPaddingException e) {
     73             // TODO Auto-generated catch block
     74             e.printStackTrace();
     75         }
     76         return null;
     77     }
     78 
     79     /**
     80      * 使用ECB解密,三步走,不说了
     81      * 
     82      * @param decodedText
     83      * @param key
     84      * @return
     85      */
     86     public static String AesEcbDecode(byte[] decodedText, SecretKey key) {
     87         try {
     88             Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
     89             cipher.init(Cipher.DECRYPT_MODE, key);
     90             return new String(cipher.doFinal(decodedText));
     91         } catch (NoSuchAlgorithmException | NoSuchPaddingException
     92                 | InvalidKeyException | IllegalBlockSizeException
     93                 | BadPaddingException e) {
     94             // TODO Auto-generated catch block
     95             e.printStackTrace();
     96         }
     97         return null;
     98 
     99     }
    100 
    101     /**
    102      * CBC加密,三步走,只是在初始化时加了一个初始变量
    103      * 
    104      * @param plainText
    105      * @param key
    106      * @param IVParameter
    107      * @return
    108      */
    109     public static byte[] AesCbcEncode(byte[] plainText, SecretKey key,
    110             byte[] IVParameter) {
    111         try {
    112             IvParameterSpec ivParameterSpec = new IvParameterSpec(IVParameter);
    113 
    114             Cipher cipher = Cipher.getInstance(CBC_CIPHER_ALGORITHM);
    115             cipher.init(Cipher.ENCRYPT_MODE, key, ivParameterSpec);
    116             return cipher.doFinal(plainText);
    117 
    118         } catch (NoSuchAlgorithmException | NoSuchPaddingException
    119                 | InvalidKeyException | InvalidAlgorithmParameterException
    120                 | IllegalBlockSizeException | BadPaddingException e) {
    121             // TODO Auto-generated catch block
    122             e.printStackTrace();
    123         }
    124         return null;
    125     }
    126 
    127     /**
    128      * CBC 解密
    129      * 
    130      * @param decodedText
    131      * @param key
    132      * @param IVParameter
    133      * @return
    134      */
    135     public static String AesCbcDecode(byte[] decodedText, SecretKey key,
    136             byte[] IVParameter) {
    137         IvParameterSpec ivParameterSpec = new IvParameterSpec(IVParameter);
    138 
    139         try {
    140             Cipher cipher = Cipher.getInstance(CBC_CIPHER_ALGORITHM);
    141             cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
    142             return new String(cipher.doFinal(decodedText));
    143         } catch (NoSuchAlgorithmException | NoSuchPaddingException
    144                 | InvalidKeyException | InvalidAlgorithmParameterException
    145                 | IllegalBlockSizeException | BadPaddingException e) {
    146             // TODO Auto-generated catch block
    147             e.printStackTrace();
    148         }
    149 
    150         return null;
    151 
    152     }
    153 
    154     /**
    155      * 1.创建一个KeyGenerator 2.调用KeyGenerator.generateKey方法
    156      * 由于某些原因,这里只能是128,如果设置为256会报异常,原因在下面文字说明
    157      * 
    158      * @return
    159      */
    160     public static byte[] generateAESSecretKey() {
    161         KeyGenerator keyGenerator;
    162         try {
    163             keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
    164             // keyGenerator.init(256);
    165             return keyGenerator.generateKey().getEncoded();
    166         } catch (NoSuchAlgorithmException e) {
    167             // TODO Auto-generated catch block
    168             e.printStackTrace();
    169         }
    170         return null;
    171     }
    172 
    173     /**
    174      * 还原密钥
    175      * 
    176      * @param secretBytes
    177      * @return
    178      */
    179     public static SecretKey restoreSecretKey(byte[] secretBytes) {
    180         SecretKey secretKey = new SecretKeySpec(secretBytes, KEY_ALGORITHM);
    181         return secretKey;
    182     }
    183 }

    因为某些国家的进口管制限制,Java发布的运行环境包中的加解密有一定的限制。比如默认不允许256位密钥的AES加解密,解决方法就是修改策略文件。

     
     官方网站提供了JCE无限制权限策略文件的下载:

      JDK6的下载地址:
      http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

      JDK7的下载地址:
      http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

    下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt。

    如果安装了JRE,将两个jar文件放到%JRE_HOME%libsecurity下覆盖原来文件,记得先备份。

    如果安装了JDK,将两个jar文件也放到%JDK_HOME%jrelibsecurity下。
     
    PS:我也没试过,不行别找我。
     
    KeyFactory最常用的操作就是通过密钥规范获得对应的密钥。像DES 3DES都是通过这样获得的,而AES只要一般的密钥规范就可以了,因此不需要KeyFactory.
  • 相关阅读:
    Facebook的体系结构分析---外文转载
    简易的IOS位置定位服务
    【简易版】IOS仿periscope自制狂赞飘桃心
    The Linux Programming Interface
    freeswitch嵌入lua脚本
    Epoll Tutorial – epoll In 3 Easy Steps!
    基于freeswitch的webrtc与sip终端呼叫
    buildroot添加第三方库
    rfc
    TCP/UDP Server-Client implementation in C
  • 原文地址:https://www.cnblogs.com/kingsleylam/p/4987064.html
Copyright © 2020-2023  润新知