• Android AES加密工具类实现(基础回顾)


      1 package com.powercreator.cms.util;
      2 
      3 import java.security.SecureRandom;
      4 import javax.crypto.Cipher;
      5 import javax.crypto.KeyGenerator;
      6 import javax.crypto.SecretKey;
      7 import javax.crypto.spec.IvParameterSpec;
      8 import javax.crypto.spec.SecretKeySpec;
      9 /**
     10  * @author vijoz
     11  * @version 创建时间:2016-6-30
     12  */
     13 public class AESUtils {
     14     public static final String TAG = "AESUtils";
     15 
     16     public static String encrypt(String seed, String clearText) {
     17         // Log.d(TAG, "加密前的seed=" + seed + ",内容为:" + clearText);
     18         byte[] result = null;
     19         try {
     20             byte[] rawkey = getRawKey(seed.getBytes());
     21             result = encrypt(rawkey, clearText.getBytes());
     22         } catch (Exception e) {
     23             e.printStackTrace();
     24         }
     25         String content = toHex(result);
     26         // Log.d(TAG, "加密后的内容为:" + content);
     27         return content;
     28     }
     29 
     30     public static String decrypt(String seed, String encrypted) {
     31         // Log.d(TAG, "解密前的seed=" + seed + ",内容为:" + encrypted);
     32         byte[] rawKey;
     33         try {
     34             rawKey = getRawKey(seed.getBytes());
     35             byte[] enc = toByte(encrypted);
     36             byte[] result = decrypt(rawKey, enc);
     37             String coentn = new String(result);
     38             // Log.d(TAG, "解密后的内容为:" + coentn);
     39             return coentn;
     40         } catch (Exception e) {
     41             e.printStackTrace();
     42             return null;
     43         }
     44 
     45     }
     46 
     47     private static byte[] getRawKey(byte[] seed) throws Exception {
     48         KeyGenerator kgen = KeyGenerator.getInstance("AES");
     49         SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
     50         sr.setSeed(seed);
     51         kgen.init(128, sr);
     52         SecretKey sKey = kgen.generateKey();
     53         byte[] raw = sKey.getEncoded();
     54         return raw;
     55     }
     56 
     57     private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
     58         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     59         // Cipher cipher = Cipher.getInstance("AES");
     60         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     61         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(
     62                 new byte[cipher.getBlockSize()]));
     63         byte[] encrypted = cipher.doFinal(clear);
     64         return encrypted;
     65     }
     66 
     67     private static byte[] decrypt(byte[] raw, byte[] encrypted)
     68             throws Exception {
     69         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     70         // Cipher cipher = Cipher.getInstance("AES");
     71         Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
     72         cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(
     73                 new byte[cipher.getBlockSize()]));
     74         byte[] decrypted = cipher.doFinal(encrypted);
     75         return decrypted;
     76     }
     77 
     78     public static String toHex(String txt) {
     79         return toHex(txt.getBytes());
     80     }
     81 
     82     public static String fromHex(String hex) {
     83         return new String(toByte(hex));
     84     }
     85 
     86     public static byte[] toByte(String hexString) {
     87         int len = hexString.length() / 2;
     88         byte[] result = new byte[len];
     89         for (int i = 0; i < len; i++)
     90             result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
     91                     16).byteValue();
     92         return result;
     93     }
     94 
     95     public static String toHex(byte[] buf) {
     96         if (buf == null)
     97             return "";
     98         StringBuffer result = new StringBuffer(2 * buf.length);
     99         for (int i = 0; i < buf.length; i++) {
    100             appendHex(result, buf[i]);
    101         }
    102         return result.toString();
    103     }
    104 
    105     private static void appendHex(StringBuffer sb, byte b) {
    106         final String HEX = "0123456789ABCDEF";
    107         sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    108     }
    109 }

     上面的实现貌似有些问题,待调试!

    下面是转发的另一个实现:

      1 import java.io.UnsupportedEncodingException;
      2 import java.security.InvalidKeyException;
      3 import java.security.Key;
      4 import java.security.NoSuchAlgorithmException;
      5 import javax.crypto.BadPaddingException;
      6 import javax.crypto.Cipher;
      7 import javax.crypto.IllegalBlockSizeException;
      8 import javax.crypto.KeyGenerator;
      9 import javax.crypto.NoSuchPaddingException;
     10 import javax.crypto.spec.SecretKeySpec;
     11 
     12 public class AES {
     13 
     14     static final String algorithmStr = "AES/ECB/PKCS5Padding";
     15 
     16     private static final Object TAG = "AES";
     17 
     18     static private KeyGenerator keyGen;
     19 
     20     static private Cipher cipher;
     21 
     22     static boolean isInited = false;
     23       
     24       private static  void init() {
     25         try { 
     26                 /**为指定算法生成一个 KeyGenerator 对象。
     27                 *此类提供(对称)密钥生成器的功能。
     28                 *密钥生成器是使用此类的某个 getInstance 类方法构造的。
     29                 *KeyGenerator 对象可重复使用,也就是说,在生成密钥后,
     30                 *可以重复使用同一 KeyGenerator 对象来生成进一步的密钥。
     31                 *生成密钥的方式有两种:与算法无关的方式,以及特定于算法的方式。
     32                 *两者之间的惟一不同是对象的初始化:
     33                 *与算法无关的初始化
     34                 *所有密钥生成器都具有密钥长度 和随机源 的概念。
     35                 *此 KeyGenerator 类中有一个 init 方法,它可采用这两个通用概念的参数。
     36                 *还有一个只带 keysize 参数的 init 方法,
     37                 *它使用具有最高优先级的提供程序的 SecureRandom 实现作为随机源
     38                 *(如果安装的提供程序都不提供 SecureRandom 实现,则使用系统提供的随机源)。
     39                 *此 KeyGenerator 类还提供一个只带随机源参数的 inti 方法。
     40                 *因为调用上述与算法无关的 init 方法时未指定其他参数,
     41                 *所以由提供程序决定如何处理将与每个密钥相关的特定于算法的参数(如果有)。
     42                 *特定于算法的初始化
     43                 *在已经存在特定于算法的参数集的情况下,
     44                 *有两个具有 AlgorithmParameterSpec 参数的 init 方法。
     45                 *其中一个方法还有一个 SecureRandom 参数,
     46                 *而另一个方法将已安装的高优先级提供程序的 SecureRandom 实现用作随机源
     47                 *(或者作为系统提供的随机源,如果安装的提供程序都不提供 SecureRandom 实现)。
     48                 *如果客户端没有显式地初始化 KeyGenerator(通过调用 init 方法),
     49                 *每个提供程序必须提供(和记录)默认初始化。
     50                 */
     51             keyGen = KeyGenerator.getInstance("AES");
     52         } catch (NoSuchAlgorithmException e) {
     53             e.printStackTrace();
     54         }
     55         // 初始化此密钥生成器,使其具有确定的密钥长度。
     56         keyGen.init(128); //128位的AES加密
     57         try {    
     58                 // 生成一个实现指定转换的 Cipher 对象。
     59             cipher = Cipher.getInstance(algorithmStr);
     60         } catch (NoSuchAlgorithmException e) {
     61             e.printStackTrace();
     62         } catch (NoSuchPaddingException e) {
     63             e.printStackTrace();
     64         }
     65         //标识已经初始化过了的字段
     66         isInited = true;
     67     }
     68 
     69     private static byte[] genKey() {
     70         if (!isInited) {
     71             init();  
     72         }
     73         //首先 生成一个密钥(SecretKey),
     74         //然后,通过这个秘钥,返回基本编码格式的密钥,如果此密钥不支持编码,则返回 null。 
     75         return keyGen.generateKey().getEncoded();
     76     }
     77 
     78     private static byte[] encrypt(byte[] content, byte[] keyBytes) {
     79         byte[] encryptedText = null;
     80         if (!isInited) { 
     81             init();
     82         }
     83         /**
     84         *类 SecretKeySpec
     85         *可以使用此类来根据一个字节数组构造一个 SecretKey,
     86         *而无须通过一个(基于 provider 的)SecretKeyFactory。
     87         *此类仅对能表示为一个字节数组并且没有任何与之相关联的钥参数的原始密钥有用 
     88         *构造方法根据给定的字节数组构造一个密钥。
     89         *此构造方法不检查给定的字节数组是否指定了一个算法的密钥。
     90         */
     91         Key key = new SecretKeySpec(keyBytes, "AES");
     92         try {
     93                 // 用密钥初始化此 cipher。
     94             cipher.init(Cipher.ENCRYPT_MODE, key);
     95         } catch (InvalidKeyException e) {
     96             e.printStackTrace();
     97         }
     98         try {
     99                 //按单部分操作加密或解密数据,或者结束一个多部分操作。(不知道神马意思)
    100             encryptedText = cipher.doFinal(content);
    101         } catch (IllegalBlockSizeException e) {
    102             e.printStackTrace();
    103         } catch (BadPaddingException e) {
    104             e.printStackTrace();
    105         }
    106         return encryptedText;
    107     }
    108 
    109     private static byte[] encrypt(String content, String password) {
    110         try {
    111             byte[] keyStr = getKey(password);
    112             SecretKeySpec key = new SecretKeySpec(keyStr, "AES");
    113             Cipher cipher = Cipher.getInstance(algorithmStr);//algorithmStr          
    114             byte[] byteContent = content.getBytes("utf-8");
    115             cipher.init(Cipher.ENCRYPT_MODE, key);//   ʼ  
    116             byte[] result = cipher.doFinal(byteContent);
    117             return result; //     
    118         } catch (NoSuchAlgorithmException e) {
    119             e.printStackTrace();
    120         } catch (NoSuchPaddingException e) {
    121             e.printStackTrace();
    122         } catch (InvalidKeyException e) {
    123             e.printStackTrace();
    124         } catch (UnsupportedEncodingException e) {
    125             e.printStackTrace();
    126         } catch (IllegalBlockSizeException e) {
    127             e.printStackTrace();
    128         } catch (BadPaddingException e) {
    129             e.printStackTrace();
    130         }
    131         return null;
    132     }
    133  
    134     private static byte[] decrypt(byte[] content, String password) {
    135         try {
    136             byte[] keyStr = getKey(password);
    137             SecretKeySpec key = new SecretKeySpec(keyStr, "AES");
    138             Cipher cipher = Cipher.getInstance(algorithmStr);//algorithmStr           
    139             cipher.init(Cipher.DECRYPT_MODE, key);//   ʼ  
    140             byte[] result = cipher.doFinal(content);
    141             return result; //     
    142         } catch (NoSuchAlgorithmException e) {
    143             e.printStackTrace();
    144         } catch (NoSuchPaddingException e) {
    145             e.printStackTrace();
    146         } catch (InvalidKeyException e) {
    147             e.printStackTrace();
    148         } catch (IllegalBlockSizeException e) {
    149             e.printStackTrace();
    150         } catch (BadPaddingException e) {
    151             e.printStackTrace();
    152         }
    153         return null;
    154     }
    155     
    156     private static byte[] getKey(String password) {
    157         byte[] rByte = null;
    158         if (password!=null) {
    159             rByte = password.getBytes();
    160         }else{
    161             rByte = new byte[24];
    162         }
    163         return rByte;
    164     }
    165 
    166     /**
    167      * 将二进制转换成16进制
    168      * @param buf
    169      * @return
    170      */
    171     public static String parseByte2HexStr(byte buf[]) {
    172         StringBuffer sb = new StringBuffer();
    173         for (int i = 0; i < buf.length; i++) {
    174             String hex = Integer.toHexString(buf[i] & 0xFF);
    175             if (hex.length() == 1) {
    176                 hex = '0' + hex;
    177             }
    178             sb.append(hex.toUpperCase());
    179         }
    180         return sb.toString();
    181     }
    182 
    183     /**
    184      * 将16进制转换为二进制
    185      * @param hexStr
    186      * @return
    187      */
    188     public static byte[] parseHexStr2Byte(String hexStr) {
    189         if (hexStr.length() < 1)
    190             return null; 
    191         byte[] result = new byte[hexStr.length() / 2];
    192         for (int i = 0; i < hexStr.length() / 2; i++) {
    193             int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
    194             int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2),
    195                     16);
    196             result[i] = (byte) (high * 16 + low);
    197         }
    198         return result;
    199     }
    200     
    201         //注意: 这里的password(秘钥必须是16位的)
    202     private static final String keyBytes = "abcdefgabcdefg12"; 
    203     
    204     /**
    205     *加密
    206     */
    207     public static String encode(String content){
    208             //加密之后的字节数组,转成16进制的字符串形式输出
    209         return parseByte2HexStr(encrypt(content, keyBytes));
    210     }
    211     
    212     /**
    213     *解密
    214     */
    215     public static String decode(String content){
    216             //解密之前,先将输入的字符串按照16进制转成二进制的字节数组,作为待解密的内容输入
    217         byte[] b = decrypt(parseHexStr2Byte(content), keyBytes);
    218         return new String(b);
    219     }
    220     
    221     //测试用例
    222     public static void test1(){
    223         String content = "hello abcdefggsdfasdfasdf";
    224         String pStr = encode(content );
    225         System.out.println("加密前:"+content);
    226         System.out.println("加密后:" + pStr);
    227         
    228         String postStr = decode(pStr);
    229         System.out.println("解密后:"+ postStr );
    230     }
    231     
    232     public static void main(String[] args) {
    233         test1();
    234     }
    235 }

     第三个,说实测兼容所有版本的:

      1 import android.annotation.SuppressLint;
      2 import java.security.SecureRandom;
      3 
      4 import javax.crypto.Cipher;
      5 import javax.crypto.KeyGenerator;
      6 import javax.crypto.SecretKey;
      7 import javax.crypto.spec.IvParameterSpec;
      8 import javax.crypto.spec.SecretKeySpec;
      9 
     10 /**
     11  * 
     12  * 
     13  * Author:sunger
     14  */
     15 public class AESUtils {
     16 
     17     public static String encrypt(String seed, String cleartext)
     18             throws Exception {
     19 
     20         byte[] rawKey = getRawKey(seed.getBytes());
     21 
     22         byte[] result = encrypt(rawKey, cleartext.getBytes());
     23 
     24         return toHex(result);
     25 
     26     }
     27 
     28     public static String decrypt(String seed, String encrypted)
     29             throws Exception {
     30 
     31         byte[] rawKey = getRawKey(seed.getBytes());
     32 
     33         byte[] enc = toByte(encrypted);
     34 
     35         byte[] result = decrypt(rawKey, enc);
     36 
     37         return new String(result);
     38 
     39     }
     40 
     41     @SuppressLint("TrulyRandom")
     42     private static byte[] getRawKey(byte[] seed) throws Exception {
     43 
     44         KeyGenerator kgen = KeyGenerator.getInstance("AES");
     45 
     46         SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
     47 
     48         sr.setSeed(seed);
     49 
     50         kgen.init(128, sr); // 192 and 256 bits may not be available
     51 
     52         SecretKey skey = kgen.generateKey();
     53 
     54         byte[] raw = skey.getEncoded();
     55 
     56         return raw;
     57 
     58     }
     59 
     60     private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
     61 
     62         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     63 
     64         Cipher cipher = Cipher.getInstance("AES");
     65 
     66         cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(
     67                 new byte[cipher.getBlockSize()]));
     68 
     69         byte[] encrypted = cipher.doFinal(clear);
     70 
     71         return encrypted;
     72 
     73     }
     74 
     75     private static byte[] decrypt(byte[] raw, byte[] encrypted)
     76             throws Exception {
     77 
     78         SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
     79 
     80         Cipher cipher = Cipher.getInstance("AES");
     81 
     82         cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(
     83                 new byte[cipher.getBlockSize()]));
     84 
     85         byte[] decrypted = cipher.doFinal(encrypted);
     86 
     87         return decrypted;
     88 
     89     }
     90 
     91     private static byte[] toByte(String hexString) {
     92 
     93         int len = hexString.length() / 2;
     94 
     95         byte[] result = new byte[len];
     96 
     97         for (int i = 0; i < len; i++)
     98 
     99             result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
    100                     16).byteValue();
    101 
    102         return result;
    103 
    104     }
    105 
    106     private static String toHex(byte[] buf) {
    107 
    108         if (buf == null)
    109 
    110             return "";
    111 
    112         StringBuffer result = new StringBuffer(2 * buf.length);
    113 
    114         for (int i = 0; i < buf.length; i++) {
    115 
    116             appendHex(result, buf[i]);
    117 
    118         }
    119 
    120         return result.toString();
    121 
    122     }
    123 
    124     private final static String HEX = "0123456789ABCDEF";
    125 
    126     private static void appendHex(StringBuffer sb, byte b) {
    127 
    128         sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    129 
    130     }
    131 
    132 }

    相关连接:http://blog.csdn.net/xinzheng_wang/article/details/9159969

    http://blog.csdn.net/randyjiawenjie/article/details/6587986

    http://blog.csdn.net/wuchuanpingstone/article/details/6715196

  • 相关阅读:
    C# Access2003操作辅助类(AccessHelper.cs)
    校园网综合管理系统(一)
    使用Devexpress开发简单进销存系统(1)数据库的建立
    软件测试(一):测试基础和缺陷管理
    异步多线程
    服务器下载文件到本地,更新服务器文件
    WCF深入浅出学习1
    利用Oracle 发送邮件(utl_smtp)
    多线程之 ThreadStart 和 ParameterizedThreadStart 委托
    javascript实现的google日历,beehive.calendar.js v0.1
  • 原文地址:https://www.cnblogs.com/vijozsoft/p/5631423.html
Copyright © 2020-2023  润新知