欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

AES加密

程序员文章站 2022-06-16 09:45:48
public class Decrypt {private static String TRANSFORMATION = “AES/GCM/NoPadding”;private static String alias = “encryptData”;private static String ANDROID_KEY_STORE = “AndroidKeyStore”;// 解密随机数@RequiresApi(api = Build.VERSION_CODES.KITKAT)public stat...
public class Decrypt {
    private static String TRANSFORMATION = "AES/GCM/NoPadding";
    private static String alias = "encryptData";
    private static String ANDROID_KEY_STORE = "AndroidKeyStore";

    // 解密随机数
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    public static String decryptRandom(String alias, String workingKey, String iv) {
        try {
            KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
            keyStore.load(null);
            KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(alias, null);
            SecretKey secretKey = secretKeyEntry.getSecretKey();
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            // 密文随机秘钥
            byte[] cipherIV = Encrypt.parseHexStr2Byte(iv);
            byte[] workingkey = Encrypt.parseHexStr2Byte(workingKey);
            GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, cipherIV);
            cipher.init(Cipher.DECRYPT_MODE, secretKey, gcmParameterSpec);
            byte[] bytes = cipher.doFinal(workingkey);
            String plaintextKey = new String(bytes);
            return plaintextKey;
        } catch (Exception e) {
            Log.i("lwx decryptRandom ", e.getMessage() + "ANDROID_KEY_STORE");
            return e.getMessage();
        }
    }
   // 解密明文
    @RequiresApi(api = Build.VERSION_CODES.KITKAT)
    @SuppressLint("WrongConstant")
    public static String decryptData(String needDecrypt, String iv, String randomiv, String workingKey) {
        try {
            KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
            keyStore.load(null);
            // 解密后的秘钥
            String randomKey = Decrypt.decryptRandom(alias, workingKey, randomiv);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            SecretKeySpec secretKeySpec = new SecretKeySpec(randomKey.getBytes("UTF-8"), TRANSFORMATION);
            byte[] cipherIv = Encrypt.parseHexStr2Byte(iv);
            GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, cipherIv);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
            byte[] bytes = Encrypt.parseHexStr2Byte(needDecrypt);
            return new String(cipher.doFinal(bytes));
        } catch (Exception e) {
            Log.i("lwx decryptData", e.getMessage());
            return e.getMessage();
        }
    }
}
```java
// 加密
public class Encrypt {
    private static String TRANSFORMATION = "AES/GCM/NoPadding";
    private static String random;
    private static String alias = "encryptData";
    private static String ANDROID_KEY_STORE = "AndroidKeyStore";

    @RequiresApi(api = Build.VERSION_CODES.M)
    private static void createKey(String alias) {
        final KeyGenerator keyGenerator;
        AlgorithmParameterSpec spec = null;
        try {
            keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE);
            Calendar start = new GregorianCalendar();
            Calendar end = new GregorianCalendar();
            end.add(Calendar.YEAR, 10);
            spec = new KeyGenParameterSpec.Builder(alias,
                    KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
                    .setCertificateNotBefore(start.getTime())
                    .setCertificateNotAfter(end.getTime())
                    .build();
            keyGenerator.init(spec);
            keyGenerator.generateKey();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 加密随机数
    @RequiresApi(api = Build.VERSION_CODES.M)
    @SuppressLint("WrongConstant")
    public static SecretBean encryptRandow(Context context) {
        // 判断keystroe密钥库中是否存在该密钥
        if (!isHaveKeyStore(alias)) {
            createKey(alias);
        }
        try {
            KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
            keyStore.load(null);
            KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(alias, null);
            SecretKey secretKey = secretKeyEntry.getSecretKey();
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] randomIV = cipher.getIV();
            byte[] bytes = cipher.doFinal(random.getBytes("UTF-8"));
            // 密文随机key 转换成字符串
            String encryRandom = parseByte2HexStr(bytes);
            String iv = parseByte2HexStr(randomIV);
            // 返回密文秘钥
            SecretBean encryptBean = new SecretBean();
            encryptBean.setCiphertextKey(encryRandom);
            encryptBean.setWorkingIV(iv);
            return encryptBean;
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("lwx random ", e.getMessage());
            return null;
        }
    }

	// **1** . 首先 生成安全随机数 用明文的安全随机数和Cipher去加密needEncrypt
    // 加密明文
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static SecretBean encryptData(String needEncrypt, Context context) {
        // 生成安全随机数
        random = getRandomKey();
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            // 明文随机key
            SecretKeySpec secretKeySpec = new SecretKeySpec(random.getBytes("UTF-8"), TRANSFORMATION);
            // 初始化 cipher
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] cipherIV = cipher.getIV();
            byte[] priencrypted = cipher.doFinal(needEncrypt.getBytes("UTF-8"));
            // 转换成密文字符串
            String encryptedText = parseByte2HexStr(priencrypted);
            String iv = parseByte2HexStr(cipherIV);
            // 通过实体类将 iv 和密文key 返回
            SecretBean encryBean = new SecretBean();
            encryBean.setCipherIV(iv);
      
            encryBean.setEncryptedText(encryptedText);
            return encryBean;
        } catch (Exception e) {
            String message = e.getMessage();
            Log.i("lwx", "massage" + message);
            return null;
        }
    }

    private static boolean isHaveKeyStore(String alias) {
        try {
            KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);
            keyStore.load(null);
            KeyStore.Entry keyentry = keyStore.getEntry(alias, null);
            if (keyentry != null) {
                return true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    // 生成安全随机数
    private static String getRandomKey() {
        String val = "";
        SecureRandom random = new SecureRandom();
        for (int i = 0; i < 16; i++) {
            String charOrNum = ((random.nextInt(2) % 2) == 0) ? "char" : "num";
            if ("char".equalsIgnoreCase(charOrNum)) {
                int choice = ((random.nextInt(2) % 2) == 0) ? 65 : 97;
                val += (char) (choice + random.nextInt(26));
            } else if ("num".equalsIgnoreCase(charOrNum)) {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }

    // byte[]转换成16进制字符串
    public static String parseByte2HexStr(byte buf[]) {
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < buf.length; i++) {
            // 将每个字节都转成16进制的
            String hex = Integer.toHexString(buf[i] & 0xFF);
            if (hex.length() == 1) {
                // 为保证格式统一,用两位16进制的表示一个字节
                hex = '0' + hex;
            }
            sb.append(hex.toUpperCase());
        }
        return sb.toString();
    }

    // 16进展字符串转换成byte[]数组
    public static byte[] parseHexStr2Byte(String hexStr) {
        if (hexStr.length() < 1)
            return null;
        // 两个16进制表示一个字节,所以字节数组大小为hexStr.length() / 2
        byte[] result = new byte[hexStr.length() / 2];
        for (int i = 0; i < hexStr.length() / 2; i++) {
            // 每次获取16进制字符串中的两个转成10进制(0-255)
            int num = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 2), 16);
            // 将10进制强转为byte
            result[i] = (byte) num;
        }
        return result;
    }
}

```java
// 工具类 调用类
public class EncryptDataUtils {
    private static final String ENCRPTDATA = "EncryptData";

    @RequiresApi(api = Build.VERSION_CODES.M)
    // 加密
    public static String encryptData(String plaintext, Context context, String workingIV, String workingKey, String iv) {
    //调用加密的明文返回的是 加密的明文
        SecretBean encryBean = Encrypt.encryptData(plaintext, context);
        // 然后加密随机数
        SecretBean encryRandom = Encrypt.encryptRandow(context);
        Log.i("lwx encrypt   bean ", encryBean.toString());
        // 保存到本地用于解密
        SharedPreferences name = context.getSharedPreferences(ENCRPTDATA, Context.MODE_PRIVATE);
        SharedPreferences.Editor edit = name.edit();
        // 将需要解密的保存
        edit.putString(workingKey, encryRandom.getCiphertextKey());
        edit.putString(workingIV, encryRandom.getWorkingIV());
        edit.putString(iv, encryBean.getCipherIV());
        edit.commit();
        // 返回加密的数据用来解密
        return encryBean.getEncryptedText();
    }

    // 解密
    @RequiresApi(api = Build.VERSION_CODES.M)
    public static String decryptData(String Ciphertext, Context context, String workingIV, String workingKey, String iv) {
        String randomIV = SecretData.getRandomIV(context, workingIV);
        String plainText = SecretData.getPlainText(context, workingKey);
        Log.i("lwx plainText", plainText);
        String cipherIV = SecretData.getCipherIV(context, iv);
        String decryptData = Decrypt.decryptData(Ciphertext, cipherIV, randomIV, plainText);
        return decryptData;
    }
}

```java
// 返回实体
package com.tdtech.esuite.cmd.encrypt;

public class SecretBean {
    private String cipherIV;
    private String CiphertextKey;
    private String workingIV;
    private String encryptedText;

    public String getCipherIV() {
        return cipherIV;
    }

    public void setCipherIV(String cipherIV) {
        this.cipherIV = cipherIV;
    }

    public String getCiphertextKey() {
        return CiphertextKey;
    }

    public void setCiphertextKey(String ciphertextKey) {
        CiphertextKey = ciphertextKey;
    }

    public String getWorkingIV() {
        return workingIV;
    }

    public void setWorkingIV(String workingIV) {
        this.workingIV = workingIV;
    }

    public String getEncryptedText() {
        return encryptedText;
    }

    public void setEncryptedText(String encryptedText) {
        this.encryptedText = encryptedText;
    }
}


// 将随机的key 和随机的Iv 保存到sp 用于解密
public class SecretData {
    private static String WORKING_KEY = "workingKey";
    private static String WORKING_IV = "randomIV";
    private static String CIPHERIV = "cipherIV";
    private static SharedPreferences sp;
    private static final String ENCRPTDATA = "EncryptData";

    public static String getRandomIV(Context context, String workingIV) {
        sp = context.getSharedPreferences(ENCRPTDATA, Context.MODE_PRIVATE);
        String iv = sp.getString(workingIV, "");
        return iv;
    }

    public static String getPlainText(Context context, String workingKey) {
        sp = context.getSharedPreferences(ENCRPTDATA, Context.MODE_PRIVATE);
        String plain = sp.getString(workingKey, "");
        return plain;
    }

    public static String getCipherIV(Context context, String cipherIV) {
        sp = context.getSharedPreferences(ENCRPTDATA, Context.MODE_PRIVATE);
        String iv = sp.getString(cipherIV, "");
        return iv;
    }
}



本文地址:https://blog.csdn.net/weixin_46297800/article/details/114292209

相关标签: java