对称加密 AES
2020-03-09 本文已影响0人
十二找十三
package com.bc.mcode.util;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
public class AesSecure {
private static final String password = "f010e34ec4a3b525";
private static final int iterationCount = 1024;
private static final int keyLength = 256;
private static final int saltLength = keyLength / 8;
public static void main(String[] args) {
Map<String, String> temp1 = encoder("18843141234", true);
Map<String, String> temp2 = encoder("18843141234", false);
System.out.println(temp1);
System.out.println(temp2);
System.out.println(decoder(temp1.get("cipher"), true, temp1.get("salt"), temp1.get("iv")));
System.out.println(decoder(temp2.get("cipher"), false, temp2.get("salt"), temp2.get("iv")));
}
/**
*
* 加密
* @param text 要加密的明文
* @param flag 阀值 true:加密结果不一样 false:加密结果一样
* @return
*/
public static HashMap<String, String> encoder(String text, boolean flag) {
Objects.requireNonNull(text);
if (flag) {
return encoderReally(text);
} else {
HashMap<String, String> temp = encoderReally(text, password);
temp.put("salt", Base64.getEncoder().encodeToString(temp.get("salt").getBytes()));
return temp;
}
}
/**
* 解密
* @param text 密文
* @param flag 阀值 true:加密结果不一样 false:加密结果一样
* @param salt 盐 当阀值为false时可以不传
* @param iv 偏移量 当阀值为false时可以不传
* @return
*/
public static String decoder(String text, boolean flag, String salt, String iv) {
Objects.requireNonNull(text);
if (flag) {
Objects.requireNonNull(salt);
Objects.requireNonNull(iv);
return decoderReally(text, salt, iv);
} else {
String temp = Base64.getEncoder().encodeToString(password.getBytes());
return decoderReally(text, temp, temp);
}
}
private static SecretKey getKey(KeySpec keySpec) {
SecretKeyFactory keyFactory = null;
try {
keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
byte[] keyBytes = new byte[0];
try {
keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
SecretKey key = new SecretKeySpec(keyBytes, "AES");
return key;
}
private static HashMap<String, String> encoderReally(String text) {
HashMap<String, String> map = new HashMap<String, String>();
try {
SecureRandom random = new SecureRandom();
byte[] salt = new byte[saltLength];
random.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), salt, iterationCount, keyLength);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = new byte[cipher.getBlockSize()];
random.nextBytes(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(cipher.ENCRYPT_MODE, getKey(keySpec), ivParameterSpec);
byte[] ciphertext = cipher.doFinal(text.getBytes("utf-8"));
Encoder encoder = Base64.getEncoder();
map.put("iv", encoder.encodeToString(iv));
map.put("salt", encoder.encodeToString(salt));
map.put("cipher", encoder.encodeToString(ciphertext));
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
private static HashMap<String, String> encoderReally(String text, String salt) {
HashMap<String, String> map = new HashMap<String, String>();
try {
byte[] saltBytes = salt.getBytes();
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, iterationCount, keyLength);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] iv = password.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(cipher.ENCRYPT_MODE, getKey(keySpec), ivParameterSpec);
byte[] ciphertext = cipher.doFinal(text.getBytes("utf-8"));
Encoder encoder = Base64.getEncoder();
map.put("iv", encoder.encodeToString(iv));
map.put("salt", encoder.encodeToString(saltBytes));
map.put("cipher", encoder.encodeToString(ciphertext));
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
private static String decoderReally(String text, String salt, String iv) {
String value = null;
Decoder decoder = Base64.getDecoder();
try {
byte[] saltBytes = decoder.decode(salt);
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, iterationCount, keyLength);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] ivBytes = decoder.decode(iv);
IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
cipher.init(cipher.DECRYPT_MODE, getKey(keySpec), ivParameterSpec);
byte[] ciphertext = cipher.doFinal(decoder.decode(text));
value = new String(ciphertext, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
}