package weaver.util; import org.springframework.util.DigestUtils; import weaver.dao.CallbackData; import weaver.dao.CallbackValidateResult; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.util.Base64; public class QiyuesuoCallbackUtils { private final String aesKey; private final String token; public QiyuesuoCallbackUtils(String aesKey, String token) { this.aesKey = aesKey; this.token = token; } /** * 回调校验 */ public CallbackValidateResult callbackValidateResult(CallbackData callbackData) { String encrypted = callbackData.getEncrypted(); String plainText; try { plainText = decrypt(encrypted); } catch (Exception e) { CallbackValidateResult result = new CallbackValidateResult(false, "解密失败", null, callbackData); result.setException(e); return result; } Long timestamp = callbackData.getTimestamp(); String nonce = callbackData.getNonce(); String signature = callbackData.getSignature(); String compSignature = toMD5(plainText + timestamp + nonce + token); if (!compSignature.equals(signature)) { return new CallbackValidateResult(false, "签名校验失败", plainText, callbackData); } return new CallbackValidateResult(true, null, plainText, callbackData); } /** * 回调原文解密 */ public String decrypt(String encryptedText) throws Exception { byte[] keyBytes = aesKey.getBytes(StandardCharsets.UTF_8); SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, 0, 16, "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] ivBytes = getHashBytes(token); IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes, 0, 16); cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec); byte[] encryptedBytes = Base64.getDecoder().decode(encryptedText); byte[] decryptedBytes = cipher.doFinal(encryptedBytes); return new String(decryptedBytes, StandardCharsets.UTF_8); } private byte[] getHashBytes(String source) throws Exception { MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); return messageDigest.digest(source.getBytes(StandardCharsets.UTF_8)); } private String toMD5(String text) { byte[] textByte = text.getBytes(StandardCharsets.UTF_8); return DigestUtils.md5DigestAsHex(textByte); } }