请求数据解密(Java)
ISV在收到AIoT创新工厂转发的请求内容后,进行数据解密计算工具类如下:
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
public class IsvEncryptor {
private static final Charset CHARSET = Charset.forName("utf-8");
private final static int BLOCK_SIZE = 32;
private byte[] aesKey;
private String accountId;
/**ask getPaddingBytes key固定长度**/
private static final Integer AES_ENCODE_KEY_LENGTH = 43;
static {
KeyGenerator keyGenForAES = null;
try {
keyGenForAES = KeyGenerator.getInstance("AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
keyGenForAES.init(128);
}
/**
* 构造函数
* @param encodingAesKey 秘钥
* @param openAccountId OpenAccountId
* @throws RuntimeException 执行失败,请查看该异常的错误信息
*/
public IsvEncryptor(String encodingAesKey, String openAccountId) throws RuntimeException {
if (null==encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
throw new RuntimeException("不合法的aesKey");
}
this.accountId = openAccountId;
aesKey = Base64.decodeBase64(encodingAesKey + "=");
}
/*
* 对密文进行解密.
* @param text 需要解密的密文
* @return 解密得到的明文
*/
public String decrypt(String text) throws RuntimeException {
byte[] originalArr;
try {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
byte[] encrypted = Base64.decodeBase64(text);
originalArr = cipher.doFinal(encrypted);
} catch (Exception e) {
throw new RuntimeException("计算解密文字错误");
}
String plainText;
String fromAccountid;
try {
byte[] bytes = removePaddingBytes(originalArr);
byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
int plainTextLegth = bytes2int(networkOrder);
plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
fromAccountid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
} catch (Exception e) {
throw new RuntimeException("计算解密文字长度不匹配");
}
if (!fromAccountid.equals(accountId)) {
throw new RuntimeException("计算解密文字accountId不匹配");
}
return plainText;
}
private static byte[] removePaddingBytes(byte[] decrypted) {
int pad = (int) decrypted[decrypted.length - 1];
if (pad < 1 || pad > BLOCK_SIZE) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
private static int bytes2int(byte[] byteArr) {
int count = 0;
for (int i = 0; i < 4; i++) {
count <<= 8;
count |= byteArr[i] & 0xff;
}
return count;
}
}