因业务需求,需要进行融合登录,根据提供融合登录方的文档内容,对AES
加密解密相关内容使用.NET CORE
来进行一次实现。使用.NET CORE
完成后,根据文档提到的密文进行解密,很遗憾解密无法完成。最终根据提供的Java
文件进行相关确认,发现文档中所表述内容与Java
示例文件中出现诸多不一致的地方。最后经过咨询并确认了以Java
示例文件中的内容为准,所以此处记录一下这个AES
加密解密的方法。
import java.security.Key;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* AES加密工具类
*
*/
public class AESCommonUtils
{
/** 16位向量 双方约定一致 */
private static final String IV = "0102030504030201";
/** 密钥 双方约定一致 */
private static final String KEY = "3EDsw9[A4W5FdS{]3W";
/** 加密模式及填充方式 */
private static final String MODE_PADDING = "AES/CBC/NoPadding";
/** 加密模式 */
private static final String MODE = "AES";
/** 编码格式 UTF-8 */
private static final String CHARSET_UTF8 = "UTF-8";
/**
* AES加密过程
*
* @param strKey
* @return
* @throws Exception
*/
public static String encrypt(String strKey, String info) throws Exception {
SecretKeySpec skeySpec = getKey(strKey);
Cipher cipher = Cipher.getInstance(MODE_PADDING);
int blockSize = cipher.getBlockSize();
byte[] dataBytes = info.getBytes(CHARSET_UTF8);
int plaintextLength = dataBytes.length;
if (plaintextLength % blockSize != 0) {
plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
}
byte[] plaintext = new byte[plaintextLength];
System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(plaintext);
// return new BASE64Encoder().encode(encrypted);
return byte2hex(encrypted);
}
/***
* AES解密
*
* @param strKey
* @param strIn
* @return
* @throws Exception
*/
public static String decrypt(String strKey, String info) throws Exception {
try {
byte[] byteResult = decrypt2Byte(strKey, info);
String result = new String(byteResult, CHARSET_UTF8);
return result;
}
catch (Exception e) {
return info;
}
}
/***
* AES解密详细过程
*
* @param strKey
* @param content
* @return
* @throws Exception
*/
private static byte[] decrypt2Byte(String strKey, String content) throws Exception {
SecretKeySpec skeySpec = getKey(strKey);
Cipher cipher = Cipher.getInstance(MODE_PADDING);
IvParameterSpec iv = new IvParameterSpec(IV.getBytes());
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
// byte[] encrypted = Base64.decode(content)
byte[] encrypted = hex2byte(content);
byte[] original = flushZeroElements(cipher.doFinal(encrypted));
return original;
}
/**
* 清除AES加密前补位的内容
*
* @param source
* @return
*/
private static byte[] flushZeroElements(byte[] source) {
int i = 0;
for (byte b : source) {
if (b == 0) {
break;
}
i++;
}
byte[] result = Arrays.copyOf(source, i);
return result;
}
/***
* 针对长度不满16的密钥进行补0操作
*
* @param strKey
* @return
* @throws Exception
*/
private static SecretKeySpec getKey(String strKey) throws Exception {
byte[] arrBTmp = strKey.getBytes();
byte[] arrB = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
for (int i = 0; i < arrBTmp.length && i < arrB.length; i++) {
arrB[i] = arrBTmp[i];
}
SecretKeySpec skeySpec = new SecretKeySpec(arrB, MODE);
return skeySpec;
}
/***
* 把16进制转成byte类型数组
*
* @param strhex
* @return
*/
public static byte[] hex2byte(String strhex) {
if (strhex == null) {
return null;
}
int l = strhex.length();
if (l % 2 == 1) {
return null;
}
byte[] b = new byte[l / 2];
for (int i = 0; i != l / 2; i++) {
b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2), 16);
}
return b;
}
/**
* 把byte数组转成16进制
*
* @param b
* @return
*/
public static String byte2hex(byte[] b) {
String hs = "";
String stmp = "";
for (int n = 0; n < b.length; n++) {
stmp = (Integer.toHexString(b[n] & 0XFF));
if (stmp.length() == 1) {
hs = hs + "0" + stmp;
}
else {
hs = hs + stmp;
}
}
return hs.toUpperCase();
}
public static void main(String[] args) {
String userInfo = "11111";
try {
userInfo = AESCommonUtils.encrypt(KEY,userInfo);
System.out.println("加密后:***" + userInfo + "===========");
userInfo= AESCommonUtils.decrypt(KEY,userInfo);
System.out.println("解密后***" + userInfo + "===========");
}
catch (Exception e) {
System.out.println("加解密异常 : " + e.toString());
}
}
}
转载请注明:清风亦平凡 » Java实现AES加解密