AES的兩種加解密方式

package com.example.fileproviderdemo;

import android.content.Intent;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

/**
 * @author wanlijun
 * @description
 * @time 2018/3/20 11:05
 */

/**
 * 網絡請求中數據加密一般採用如下方式:
 * 前端用RSA公鑰加密AES的key和iv
 * AES加密要傳輸的數據
 * 後臺用RSA私鑰解密出key和iv
 * 再用AES解密出傳輸的數據
 * 後臺將查詢到的數據用AES加密傳輸給前端
 * 前端用自己的key和iv用AES解密出獲得的數據
 */

public class AESUtils {
    /** 算法/模式/填充 **/
    private static final String CipherMode = "AES/CBC/PKCS5Padding";
    private static final String HEX = "0123456789ABCDEF";
    public static final String MY_SEED = "howdoyoudo";
    /** Android6.0以下適用,6.0及以上不適用,6.0以上加密後得到的數據爲空**/
    public static String encrypt(String seed,String cleartext){
        byte[] result = null;
        try {
            byte[] rawKey = getRawKey(seed.getBytes());
            SecretKeySpec secretKeySpec = new SecretKeySpec(rawKey,"AES");
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,new IvParameterSpec(new byte[cipher.getBlockSize()]));
            result = cipher.doFinal(cleartext.getBytes());
        }catch (Exception e){
            e.printStackTrace();
        }
        return toHex(result);
    }
    public static String decrypt(String seed,String ciphertext){
        String content = null;
        try {
            byte[] rawKey = getRawKey(seed.getBytes());
            byte[] dec = toByte(ciphertext);
            SecretKeySpec secretKeySpec = new SecretKeySpec(rawKey,"AES");
            Cipher cipher = Cipher.getInstance(CipherMode);
            cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,new IvParameterSpec(new byte[cipher.getBlockSize()]));
            byte[] result = cipher.doFinal(dec);
            content = new String(result);
        }catch (Exception e){
            e.printStackTrace();
        }
        return content;
    }
    private static byte[] getRawKey(byte[] seed) throws Exception{
        KeyGenerator generator = KeyGenerator.getInstance("AES");
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "Crypto");
        secureRandom.setSeed(seed);
        generator.init(128,secureRandom);
        SecretKey key = generator.generateKey();
        return key.getEncoded();
    }
    public static String toHex(byte[] buf){
        if(buf == null){
            return "";
        }
        StringBuffer sb = new StringBuffer(2*buf.length);
        for(int i=0;i<buf.length;i++){
            sb.append(HEX.charAt((buf[i]>>4) & 0x0f)).append(HEX.charAt(buf[i] & 0x0f));
        }
        return sb.toString();
    }
    public static byte[] toByte(String hexString){
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for(int i=0;i<len;i++){
            result[i] = Integer.valueOf(hexString.substring(2*i,2*i+2),16).byteValue();
        }
        return  result;
    }

    
 /** Android6.0及以上適用,6.0以下不適用,6.0以下加密後得到的數據爲空**/
public static String encrypt(String cleartext,String key,String iv){ String ciphertext = ""; try { byte[] data = cleartext.getBytes("UTF-8"); SecretKeySpec secretKeySpec = createKey(key); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.ENCRYPT_MODE,secretKeySpec,createIv(iv)); byte[] result = cipher.doFinal(data); ciphertext = byte2Hex(result); }catch (Exception e){ e.printStackTrace(); } return ciphertext; } public static String decrypt(String ciphertext,String key,String iv){ String cleartext = ""; try { byte[] data = hex2Byte(ciphertext); SecretKeySpec secretKeySpec = createKey(key); Cipher cipher = Cipher.getInstance(CipherMode); cipher.init(Cipher.DECRYPT_MODE,secretKeySpec,createIv(iv)); byte[] result = cipher.doFinal(data); cleartext = new String(result,"UTF-8"); }catch (Exception e){ e.printStackTrace(); } return cleartext; } private static SecretKeySpec createKey(String key){ byte[] data = null; if(key == null){ key = ""; } StringBuffer sb = new StringBuffer(16); sb.append(key); while (sb.length()<16){ sb.append("0"); } if(sb.length() > 16){ sb.setLength(16); } try { data = sb.toString().getBytes("UTF-8"); }catch (Exception e){ e.printStackTrace(); } return new SecretKeySpec(data,"AES"); } private static IvParameterSpec createIv(String iv){ byte[] data = null; if(iv == null){ iv = ""; } StringBuffer sb = new StringBuffer(16); sb.append(iv); while (sb.length() < 16){ sb.append("0"); } if(sb.length() > 16){ sb.setLength(16); } try { data = sb.toString().getBytes("UTF-8"); }catch (Exception e){ e.printStackTrace(); } return new IvParameterSpec(data); } private static String byte2Hex(byte[] bytes){ StringBuffer sb = new StringBuffer(bytes.length * 2); String temp = ""; for(int i=0;i<bytes.length;i++){ temp = Integer.toHexString(bytes[i] & 0xff); if(temp.length() == 1){ sb.append("0"); } sb.append(temp); } return sb.toString().toUpperCase(); } private static byte[] hex2Byte(String hexString){ if(hexString == null || hexString.length() < 2){ return new byte[0]; } hexString = hexString.toLowerCase(); int len = hexString.length() / 2; byte[] result = new byte[len]; for(int i=0;i<len;i++){ String temp = hexString.substring(2*i,2*i+2); result[i] = (byte)(Integer.parseInt(temp,16) & 0XFF); } return result; }}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章