package com.qianwen.smartman.modules.sync.util; import com.alibaba.fastjson.JSON; import java.io.ByteArrayOutputStream; import java.lang.reflect.Field; import java.nio.charset.Charset; import java.security.MessageDigest; import java.security.Permission; import java.security.PermissionCollection; import java.security.Security; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Random; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import org.apache.commons.codec.binary.Base64; /* loaded from: blade-api.jar:BOOT-INF/classes/org/springblade/modules/sync/util/DingCallbackCrypto.class */ public class DingCallbackCrypto { private byte[] aesKey; private String token; private String corpId; private static final Charset CHARSET = Charset.forName("utf-8"); private static final Base64 base64 = new Base64(); private static final Integer AES_ENCODE_KEY_LENGTH = 43; private static final Integer RANDOM_LENGTH = 16; static { try { Security.setProperty("crypto.policy", "limited"); RemoveCryptographyRestrictions(); } catch (Exception e) { } } public DingCallbackCrypto(String token, String encodingAesKey, String corpId) throws DingTalkEncryptException { if (null == encodingAesKey || encodingAesKey.length() != AES_ENCODE_KEY_LENGTH.intValue()) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.AES_KEY_ILLEGAL)); } this.token = token; this.corpId = corpId; this.aesKey = Base64.decodeBase64(encodingAesKey + "="); } public Map getEncryptedMap(String plaintext) throws DingTalkEncryptException { return getEncryptedMap(plaintext, Long.valueOf(System.currentTimeMillis()), Utils.getRandomStr(16)); } public Map getEncryptedMap(String plaintext, Long timeStamp, String nonce) throws DingTalkEncryptException { if (null == plaintext) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL)); } if (null == timeStamp) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.ENCRYPTION_TIMESTAMP_ILLEGAL)); } if (null == nonce) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL)); } String encrypt = encrypt(Utils.getRandomStr(RANDOM_LENGTH.intValue()), plaintext); String signature = getSignature(this.token, String.valueOf(timeStamp), nonce, encrypt); Map resultMap = new HashMap<>(); resultMap.put("msg_signature", signature); resultMap.put("encrypt", encrypt); resultMap.put("timeStamp", String.valueOf(timeStamp)); resultMap.put("nonce", nonce); return resultMap; } public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg) throws DingTalkEncryptException { String signature = getSignature(this.token, timeStamp, nonce, encryptMsg); if (!signature.equals(msgSignature)) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR)); } String result = decrypt(encryptMsg); return result; } private String encrypt(String random, String plaintext) throws DingTalkEncryptException { try { byte[] randomBytes = random.getBytes(CHARSET); byte[] plainTextBytes = plaintext.getBytes(CHARSET); byte[] lengthByte = Utils.int2Bytes(plainTextBytes.length); byte[] corpidBytes = this.corpId.getBytes(CHARSET); ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); byteStream.write(randomBytes); byteStream.write(lengthByte); byteStream.write(plainTextBytes); byteStream.write(corpidBytes); byte[] padBytes = PKCS7Padding.getPaddingBytes(byteStream.size()); byteStream.write(padBytes); byte[] unencrypted = byteStream.toByteArray(); byteStream.close(); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16); cipher.init(1, keySpec, iv); byte[] encrypted = cipher.doFinal(unencrypted); String result = base64.encodeToString(encrypted); return result; } catch (Exception e) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR)); } } private String decrypt(String text) throws DingTalkEncryptException { try { Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES"); IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16)); cipher.init(2, keySpec, iv); byte[] encrypted = Base64.decodeBase64(text); byte[] originalArr = cipher.doFinal(encrypted); try { byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr); byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20); int plainTextLegth = Utils.bytes2int(networkOrder); String plainText = new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET); String fromCorpid = new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET); if (!fromCorpid.equals(this.corpId)) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR)); } return plainText; } catch (Exception e) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR)); } } catch (Exception e2) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR)); } } public String getSignature(String token, String timestamp, String nonce, String encrypt) throws DingTalkEncryptException { try { String[] array = {token, timestamp, nonce, encrypt}; Arrays.sort(array); System.out.println(JSON.toJSONString(array)); StringBuffer sb = new StringBuffer(); for (int i = 0; i < 4; i++) { sb.append(array[i]); } String str = sb.toString(); System.out.println(str); MessageDigest md = MessageDigest.getInstance("SHA-1"); md.update(str.getBytes()); byte[] digest = md.digest(); StringBuffer hexstr = new StringBuffer(); for (byte b : digest) { String shaHex = Integer.toHexString(b & 255); if (shaHex.length() < 2) { hexstr.append(0); } hexstr.append(shaHex); } return hexstr.toString(); } catch (Exception e) { throw new DingTalkEncryptException(Integer.valueOf((int) DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR)); } } /* loaded from: blade-api.jar:BOOT-INF/classes/org/springblade/modules/sync/util/DingCallbackCrypto$Utils.class */ public static class Utils { public static String getRandomStr(int count) { Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < count; i++) { int number = random.nextInt("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".length()); sb.append("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789".charAt(number)); } return sb.toString(); } public static byte[] int2Bytes(int count) { byte[] byteArr = {(byte) ((count >> 24) & 255), (byte) ((count >> 16) & 255), (byte) ((count >> 8) & 255), (byte) (count & 255)}; return byteArr; } public static int bytes2int(byte[] byteArr) { int count = 0; for (int i = 0; i < 4; i++) { count = (count << 8) | (byteArr[i] & 255); } return count; } } /* loaded from: blade-api.jar:BOOT-INF/classes/org/springblade/modules/sync/util/DingCallbackCrypto$PKCS7Padding.class */ public static class PKCS7Padding { private static final Charset CHARSET = Charset.forName("utf-8"); private static final int BLOCK_SIZE = 32; public static byte[] getPaddingBytes(int count) { int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE); if (amountToPad == 0) { amountToPad = BLOCK_SIZE; } char padChr = chr(amountToPad); String tmp = new String(); for (int index = 0; index < amountToPad; index++) { tmp = tmp + padChr; } return tmp.getBytes(CHARSET); } public static byte[] removePaddingBytes(byte[] decrypted) { int pad = decrypted[decrypted.length - 1]; if (pad < 1 || pad > BLOCK_SIZE) { pad = 0; } return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad); } private static char chr(int a) { byte target = (byte) (a & 255); return (char) target; } } /* loaded from: blade-api.jar:BOOT-INF/classes/org/springblade/modules/sync/util/DingCallbackCrypto$DingTalkEncryptException.class */ public static class DingTalkEncryptException extends Exception { public static final int SUCCESS = 0; public static final int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001; public static final int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002; public static final int ENCRYPTION_NONCE_ILLEGAL = 900003; public static final int AES_KEY_ILLEGAL = 900004; public static final int SIGNATURE_NOT_MATCH = 900005; public static final int COMPUTE_SIGNATURE_ERROR = 900006; public static final int COMPUTE_ENCRYPT_TEXT_ERROR = 900007; public static final int COMPUTE_DECRYPT_TEXT_ERROR = 900008; public static final int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009; public static final int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010; private static Map msgMap = new HashMap(); private Integer code; static { msgMap.put(0, "成功"); msgMap.put(Integer.valueOf((int) ENCRYPTION_PLAINTEXT_ILLEGAL), "加密明文文本非法"); msgMap.put(Integer.valueOf((int) ENCRYPTION_TIMESTAMP_ILLEGAL), "加密时间戳参数非法"); msgMap.put(Integer.valueOf((int) ENCRYPTION_NONCE_ILLEGAL), "加密随机字符串参数非法"); msgMap.put(Integer.valueOf((int) SIGNATURE_NOT_MATCH), "签名不匹配"); msgMap.put(Integer.valueOf((int) COMPUTE_SIGNATURE_ERROR), "签名计算失败"); msgMap.put(Integer.valueOf((int) AES_KEY_ILLEGAL), "不合法的aes key"); msgMap.put(Integer.valueOf((int) COMPUTE_ENCRYPT_TEXT_ERROR), "计算加密文字错误"); msgMap.put(Integer.valueOf((int) COMPUTE_DECRYPT_TEXT_ERROR), "计算解密文字错误"); msgMap.put(Integer.valueOf((int) COMPUTE_DECRYPT_TEXT_LENGTH_ERROR), "计算解密文字长度不匹配"); msgMap.put(Integer.valueOf((int) COMPUTE_DECRYPT_TEXT_CORPID_ERROR), "计算解密文字corpid不匹配"); } public Integer getCode() { return this.code; } public DingTalkEncryptException(Integer exceptionCode) { super(msgMap.get(exceptionCode)); this.code = exceptionCode; } } private static void RemoveCryptographyRestrictions() throws Exception { Class jceSecurity = getClazz("javax.crypto.JceSecurity"); Class cryptoPermissions = getClazz("javax.crypto.CryptoPermissions"); Class cryptoAllPermission = getClazz("javax.crypto.CryptoAllPermission"); if (jceSecurity != null) { setFinalStaticValue(jceSecurity, "isRestricted", false); PermissionCollection defaultPolicy = (PermissionCollection) getFieldValue(jceSecurity, "defaultPolicy", null, PermissionCollection.class); if (cryptoPermissions != null) { Map map = (Map) getFieldValue(cryptoPermissions, "perms", defaultPolicy, Map.class); map.clear(); } if (cryptoAllPermission != null) { Permission permission = (Permission) getFieldValue(cryptoAllPermission, "INSTANCE", null, Permission.class); defaultPolicy.add(permission); } } } private static Class getClazz(String className) { Class clazz = null; try { clazz = Class.forName(className); } catch (Exception e) { } return clazz; } private static void setFinalStaticValue(Class srcClazz, String fieldName, Object newValue) throws Exception { Field field = srcClazz.getDeclaredField(fieldName); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & (-17)); field.set(null, newValue); } private static T getFieldValue(Class srcClazz, String fieldName, Object owner, Class dstClazz) throws Exception { Field field = srcClazz.getDeclaredField(fieldName); field.setAccessible(true); return dstClazz.cast(field.get(owner)); } }