AES加密
程序员文章站
2022-03-23 10:37:34
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
下一篇: 2021-03-03