对称加密相关API

image.png
/**
* Aes 的Cipher 具体实现类是 AESCrypt
*
* @author huyanbing
* @create 2022/12/16 2:39 下午
*/
public class AESTest {
private final int keyLen;
private final SecretKey key;
private String algorithm = "AES";
/**
* 构造函数
*
* @param keyLen
* @param plainKey
*/
public AESTest(int keyLen, String plainKey) {
//验证密钥长度是不是合规的
assert keyLen == 128 || keyLen == 192 || keyLen == 256;
this.keyLen = keyLen;
if (plainKey == null) {
key = generateKey();
} else {
key = importKey(plainKey);
}
}
/**
* 生成默认密钥
*
* @return
*/
public SecretKey generateKey() {
try {
//静态工厂模式
KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
keyGen.init(keyLen);
SecretKey key = keyGen.generateKey();
return key;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 导入密钥
*
* @param plainKey
* @return
*/
public SecretKey importKey(String plainKey) {
byte[] keyBytes = plainKey.getBytes();
//=> keyLen/8
assert keyBytes.length == keyLen >> 3;
return new SecretKeySpec(keyBytes, algorithm);
}
/**
* 一次加密
*
* @param plainText
* @return
* @throws Exception
*/
public byte[] encrypt(byte[] plainText) throws Exception {
Cipher aes = Cipher.getInstance(algorithm);
//Cipher.ENCRYPT_MODE 1 加密模式
aes.init(Cipher.ENCRYPT_MODE, key);
//如果数据比较多,需要不断的调用aes.update 来 迭代你的数据, 如果数据比较少 直接调用doFinal就可以了
//aes.update(plainText);
return aes.doFinal(plainText);
}
/**
* 一次解密
*
* @param cipherText
* @return
* @throws Exception
*/
public byte[] decrypt(byte[] cipherText) throws Exception {
Cipher aes = Cipher.getInstance(algorithm);
aes.init(Cipher.DECRYPT_MODE, key);
//aes.update(cipherText);
return aes.doFinal(cipherText);
}
public static void main(String[] args) throws Exception {
// AESTest test = new AESTest(128, null);
AESTest test = new AESTest(128, "0123456789012345");
//打印当前的 key
String hex = HexCustomUtil.byteArrayToHexStr(test.key.getEncoded());
System.out.println("---------key----------------");
System.out.println(hex);
//明文 PlainText
byte[] plainText = "AES加密体制也是由多轮加密构成,除了结尾的一轮,其他轮都是由四个步骤组成——字节代替、行移位、列混淆、轮密钥加。而最后一轮仅包括字节代替、行移位、轮密钥加这三步。AES迭代的轮数与密钥的长度相关,16字节的密钥对应着迭代10轮,24字节的密钥对应着迭代12轮,32字节的密钥对应着迭代14轮。在开始所有轮迭代之前,需要进行一次初始变换——一次轮密钥加,这一步往往被称为第0轮。".getBytes();
//加密
byte[] cipherText = test.encrypt(plainText);
//打印密文
System.out.println("---------密文----------------");
System.out.println(HexCustomUtil.byteArrayToHexStr(cipherText));
byte[] decryptArr = test.decrypt(cipherText);
System.out.println("---------解密后明文----------------");
System.out.println(new String(decryptArr));
}
}
public class HexCustomUtil {
/*输入16进制byte[]输出16进制字符串*/
public static String byteArrayToHexStr(byte[] byteArray) {
if (byteArray == null) {
return null;
}
char[] hexArray = "0123456789ABCDEF".toCharArray();
char[] hexChars = new char[byteArray.length * 2];
for (int j = 0; j < byteArray.length; j++) {
int v = byteArray[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
网友评论