• 使用java进行 AES 加密 解密?


    百度百科是这样定义的:

         高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001年11月26日发布于FIPS PUB 197,并在2002年5月26日成为有效的标准。2006年,高级加密标准已然成为对称密钥加密中最流行的算法之一。

      1 import java.io.UnsupportedEncodingException;
      2  
      3 import javax.crypto.Cipher;  
      4 import javax.crypto.spec.IvParameterSpec;  
      5 import javax.crypto.spec.SecretKeySpec;
      6  
      7 import com.sun.org.apache.regexp.internal.recompile;
      8  
      9 import sun.misc.BASE64Decoder;  
     10 import sun.misc.BASE64Encoder;  
     11   
     12 public class MainTest {  
     13   
     14     //偏移量
     15     public static final String VIPARA = "1234567876543210";   //AES 为16bytes. DES 为8bytes  
     16       
     17     //编码方式
     18     public static final String CODE_TYPE = "UTF-8";
     19 //  public static final String CODE_TYPE = "GBK";
     20     
     21     //填充类型
     22     public static final String AES_TYPE = "AES/ECB/PKCS5Padding";
     23     //public static final String AES_TYPE = "AES/ECB/PKCS7Padding";
     24     //此类型 加密内容,密钥必须为16字节的倍数位,否则抛异常,需要字节补全再进行加密
     25 //    public static final String AES_TYPE = "AES/ECB/NoPadding";
     26     //java 不支持ZeroPadding
     27     //public static final String AES_TYPE = "AES/CBC/ZeroPadding";
     28       
     29     //私钥  
     30     private static final String AES_KEY="1111222233334444";   //AES固定格式为128/192/256 bits.即:16/24/32bytes。DES固定格式为128bits,即8bytes。  
     31     
     32     //字符补全
     33     private static final String[] consult = new String[]{"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G"};
     34  
     35     
     36     /** 
     37      * 加密 
     38      *  
     39      * @param cleartext 
     40      * @return 
     41      */  
     42     public static String encrypt(String cleartext) {  
     43         //加密方式: AES128(CBC/PKCS5Padding) + Base64, 私钥:1111222233334444  
     44         try {  
     45             IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());  
     46             //两个参数,第一个为私钥字节数组, 第二个为加密方式 AES或者DES  
     47             SecretKeySpec key = new SecretKeySpec(AES_KEY.getBytes(), "AES");  
     48             //实例化加密类,参数为加密方式,要写全  
     49             Cipher cipher = Cipher.getInstance(AES_TYPE); //PKCS5Padding比PKCS7Padding效率高,PKCS7Padding可支持IOS加解密  
     50             //初始化,此方法可以采用三种方式,按加密算法要求来添加。(1)无第三个参数(2)第三个参数为SecureRandom random = new SecureRandom();中random对象,随机数。(AES不可采用这种方法)(3)采用此代码中的IVParameterSpec  
     51             //加密时使用:ENCRYPT_MODE;  解密时使用:DECRYPT_MODE;
     52             cipher.init(Cipher.ENCRYPT_MODE, key); //CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量
     53             //加密操作,返回加密后的字节数组,然后需要编码。主要编解码方式有Base64, HEX, UUE,7bit等等。此处看服务器需要什么编码方式 
     54             byte[] encryptedData = cipher.doFinal(cleartext.getBytes(CODE_TYPE));  
     55   
     56             return new BASE64Encoder().encode(encryptedData);  
     57         } catch (Exception e) {  
     58             e.printStackTrace();  
     59             return "";   
     60         }  
     61     }  
     62   
     63     /** 
     64      * 解密 
     65      *  
     66      * @param encrypted 
     67      * @return 
     68      */  
     69     public static String decrypt(String encrypted) {  
     70         try {  
     71             byte[] byteMi = new BASE64Decoder().decodeBuffer(encrypted);  
     72             IvParameterSpec zeroIv = new IvParameterSpec(VIPARA.getBytes());  
     73             SecretKeySpec key = new SecretKeySpec(  
     74                     AES_KEY.getBytes(), "AES");  
     75             Cipher cipher = Cipher.getInstance(AES_TYPE);  
     76             //与加密时不同MODE:Cipher.DECRYPT_MODE  
     77             cipher.init(Cipher.DECRYPT_MODE, key);  //CBC类型的可以在第三个参数传递偏移量zeroIv,ECB没有偏移量
     78             byte[] decryptedData = cipher.doFinal(byteMi);  
     79             return new String(decryptedData, CODE_TYPE);  
     80         } catch (Exception e) {  
     81             e.printStackTrace();  
     82             return "";  
     83         }  
     84     }  
     85   
     86     /** 
     87      * 测试 
     88      *  
     89      * @param args 
     90      * @throws Exception 
     91      */  
     92     public static void main(String[] args) throws Exception {  
     93         String content = "AES加密";
     94         test(content);
     95     }
     96     
     97     public static void test(String content) throws UnsupportedEncodingException{
     98         System.out.println("加密内容:" + content);
     99         //字节数
    100         int num = content.getBytes(CODE_TYPE).length; 
    101         System.out.println("加密内容字节数: " + num);
    102       
    103         //字节补全
    104         if(AES_TYPE.equals("AES/ECB/NoPadding")){
    105             System.out.println();
    106             content = completionCodeFor16Bytes(content);
    107             System.out.println("加密内容补全后: "+content);
    108         }
    109         
    110         System.out.println();
    111         
    112         // 加密
    113         String encryptResult = encrypt(content);  
    114         content = new String(encryptResult);
    115         System.out.println("加密后:" + content);
    116         
    117         System.out.println();
    118         
    119         // 解密
    120         String decryptResult = decrypt(encryptResult);
    121         content = new String(decryptResult);
    122         //还原
    123         if(AES_TYPE.equals("AES/ECB/NoPadding")){
    124             System.out.println("解密内容还原前: "+content);
    125             content = resumeCodeOf16Bytes(content);
    126         }
    127         
    128         System.out.println("解密完成后:" + content);  
    129     }
    130     
    131     
    132     
    133     
    134     //NoPadding 
    135     //补全字符
    136     public static String completionCodeFor16Bytes(String str) throws UnsupportedEncodingException{
    137         int num = str.getBytes(CODE_TYPE).length;
    138         int index = num%16;
    139         //进行加密内容补全操作, 加密内容应该为 16字节的倍数, 当不足16*n字节是进行补全, 差一位时 补全16+1位
    140         //补全字符 以 $ 开始,$后一位代表$后补全字符位数,之后全部以0进行补全;
    141         if(index != 0){
    142             StringBuffer sbBuffer = new StringBuffer(str);
    143             if(16-index == 1){
    144                 sbBuffer.append("$" + consult[16-1] + addStr(16-1-1));
    145             }else{
    146                 sbBuffer.append("$" + consult[16-index-1] + addStr(16-index-1-1));
    147             }
    148             str = sbBuffer.toString();
    149         }
    150         return str;
    151     }
    152     
    153     //追加字符
    154     public static String addStr(int num){
    155         StringBuffer sbBuffer = new StringBuffer("");
    156         for (int i = 0; i < num; i++) {
    157             sbBuffer.append("0");
    158         }
    159         return sbBuffer.toString();
    160     }
    161     
    162     
    163     //还原字符(进行字符判断)
    164     public static String resumeCodeOf16Bytes(String str){
    165         int indexOf = str.lastIndexOf("$");
    166 //        System.out.println(indexOf);
    167         if(indexOf == -1){
    168             return str;
    169         }
    170         String trim = str.substring(indexOf+1,indexOf+2).trim();
    171 //        System.out.println(trim);
    172         int num = 0;
    173         for (int i = 0; i < consult.length; i++) {
    174             if(trim.equals(consult[i])){
    175                 num = i;
    176             }
    177         }
    178         if(num == 0){
    179             return str;
    180         }
    181         return str.substring(0,indexOf).trim();
    182     }
    183     
    184 } 
  • 相关阅读:
    C#拾遗系列(2):属性
    都江堰我永远支持你
    【号外】2011 Autodesk开发者日又来啦~~
    DB_RUNRECOVERY: Fatal error, run database recovery StackTrace问题的解决办法
    [书友交流] <Autodesk 地理信息系统解决方案FDO、MapGuide、AutoCAD Map 3D二次开发指南>读书交流贴
    Autodesk Infrastructure Map Server 2012 SP1 Released!
    Map3D中获取地图中心及Zoom到新的中心点
    Introduction to MapGuide OpenSource – from FOSS4G in Denver
    获取选中地物的Geometry对象,及把Geometry对象显示在地图上
    [在线技术活动]Civil 3D 部件编辑器详解
  • 原文地址:https://www.cnblogs.com/fenghh/p/9718888.html
Copyright © 2020-2023  润新知