请求数据解密(Java)

ISV在收到AIoT创新工厂转发的请求内容后,进行数据解密计算工具类如下:

  1. import org.apache.commons.codec.binary.Base64;
  2. import javax.crypto.Cipher;
  3. import javax.crypto.KeyGenerator;
  4. import javax.crypto.spec.IvParameterSpec;
  5. import javax.crypto.spec.SecretKeySpec;
  6. import java.nio.charset.Charset;
  7. import java.security.NoSuchAlgorithmException;
  8. import java.util.Arrays;
  9. public class IsvEncryptor {
  10. private static final Charset CHARSET = Charset.forName("utf-8");
  11. private final static int BLOCK_SIZE = 32;
  12. private byte[] aesKey;
  13. private String accountId;
  14. /**ask getPaddingBytes key固定长度**/
  15. private static final Integer AES_ENCODE_KEY_LENGTH = 43;
  16. static {
  17. KeyGenerator keyGenForAES = null;
  18. try {
  19. keyGenForAES = KeyGenerator.getInstance("AES");
  20. } catch (NoSuchAlgorithmException e) {
  21. e.printStackTrace();
  22. }
  23. keyGenForAES.init(128);
  24. }
  25. /**
  26. * 构造函数
  27. * @param encodingAesKey 秘钥
  28. * @param openAccountId OpenAccountId
  29. * @throws RuntimeException 执行失败,请查看该异常的错误信息
  30. */
  31. public IsvEncryptor(String encodingAesKey, String openAccountId) throws RuntimeException {
  32. if (null==encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH) {
  33. throw new RuntimeException("不合法的aesKey");
  34. }
  35. this.accountId = openAccountId;
  36. aesKey = Base64.decodeBase64(encodingAesKey + "=");
  37. }
  38. /*
  39. * 对密文进行解密.
  40. * @param text 需要解密的密文
  41. * @return 解密得到的明文
  42. */
  43. public String decrypt(String text) throws RuntimeException {
  44. byte[] originalArr;
  45. try {
  46. Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
  47. SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
  48. IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));
  49. cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
  50. byte[] encrypted = Base64.decodeBase64(text);
  51. originalArr = cipher.doFinal(encrypted);
  52. } catch (Exception e) {
  53. throw new RuntimeException("计算解密文字错误");
  54. }
  55. String plainText;
  56. String fromAccountid;
  57. try {
  58. byte[] bytes = removePaddingBytes(originalArr);
  59. byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);
  60. int plainTextLegth = bytes2int(networkOrder);
  61. plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);
  62. fromAccountid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);
  63. } catch (Exception e) {
  64. throw new RuntimeException("计算解密文字长度不匹配");
  65. }
  66. if (!fromAccountid.equals(accountId)) {
  67. throw new RuntimeException("计算解密文字accountId不匹配");
  68. }
  69. return plainText;
  70. }
  71. private static byte[] removePaddingBytes(byte[] decrypted) {
  72. int pad = (int) decrypted[decrypted.length - 1];
  73. if (pad < 1 || pad > BLOCK_SIZE) {
  74. pad = 0;
  75. }
  76. return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
  77. }
  78. private static int bytes2int(byte[] byteArr) {
  79. int count = 0;
  80. for (int i = 0; i < 4; i++) {
  81. count <<= 8;
  82. count |= byteArr[i] & 0xff;
  83. }
  84. return count;
  85. }
  86. }