无关风月
4 天以前 4742874ad840d7e1e3ac79dc288b38e9a642319d
cloud-server-activity/src/main/java/com/dsh/activity/util/wx/WxPayAesUtil.java
@@ -1,57 +1,57 @@
package com.dsh.activity.util.wx;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
/**
 * 微信支付V3 AES解密工具类 (AEAD_AES_256_GCM)
 */
public class WxPayAesUtil {
    private static final String ALGORITHM = "AES/GCM/NoPadding";
    private static final int TAG_LENGTH_BIT = 128; // GCM认证标签长度,固定为128位
    private static final int NONCE_LENGTH_BYTE = 12; // GCM随机串长度,固定为12字节
    private static final String TRANSFORMATION = "AES/GCM/NoPadding"; // 算法/模式/填充
    /**
     * 解密微信支付回调通知中的加密信息
     *
     * @param apiV3Key      APIv3密钥 (来自 WxV3PayConfig)
     * @param associatedData 附加数据 (resource.associated_data)
     * @param nonce         随机串 (resource.nonce)
     * @param ciphertext    密文 (resource.ciphertext),Base64编码
     * @return 解密后的明文字符串
     * @throws GeneralSecurityException 解密失败时抛出异常
     */
    public static String decrypt(String apiV3Key, String associatedData, String nonce, String ciphertext)
            throws GeneralSecurityException {
        try {
            SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(StandardCharsets.UTF_8), "AES");
            GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes(StandardCharsets.UTF_8));
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, key, spec);
            cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8)); // 设置附加认证数据
            byte[] decodedCiphertext = Base64.getDecoder().decode(ciphertext);
            byte[] decryptedBytes = cipher.doFinal(decodedCiphertext);
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new IllegalStateException("当前JDK环境不支持AEAD_AES_256_GCM", e);
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            throw new IllegalArgumentException("无效的密钥或GCM参数", e);
        } catch (Exception e) {
            // 包括 BadPaddingException 等解密失败的情况
            throw new GeneralSecurityException("AES/GCM 解密失败", e);
        }
    }
}
//package com.dsh.activity.util.wx;
//
//import javax.crypto.Cipher;
//import javax.crypto.NoSuchPaddingException;
//import javax.crypto.spec.GCMParameterSpec;
//import javax.crypto.spec.SecretKeySpec;
//import java.nio.charset.StandardCharsets;
//import java.security.GeneralSecurityException;
//import java.security.InvalidAlgorithmParameterException;
//import java.security.InvalidKeyException;
//import java.security.NoSuchAlgorithmException;
//import java.util.Base64;
//
///**
// * 微信支付V3 AES解密工具类 (AEAD_AES_256_GCM)
// */
//public class WxPayAesUtil {
//
//    private static final String ALGORITHM = "AES/GCM/NoPadding";
//    private static final int TAG_LENGTH_BIT = 128; // GCM认证标签长度,固定为128位
//    private static final int NONCE_LENGTH_BYTE = 12; // GCM随机串长度,固定为12字节
//    private static final String TRANSFORMATION = "AES/GCM/NoPadding"; // 算法/模式/填充
//
//    /**
//     * 解密微信支付回调通知中的加密信息
//     *
//     * @param apiV3Key      APIv3密钥 (来自 WxV3PayConfig)
//     * @param associatedData 附加数据 (resource.associated_data)
//     * @param nonce         随机串 (resource.nonce)
//     * @param ciphertext    密文 (resource.ciphertext),Base64编码
//     * @return 解密后的明文字符串
//     * @throws GeneralSecurityException 解密失败时抛出异常
//     */
//    public static String decrypt(String apiV3Key, String associatedData, String nonce, String ciphertext)
//            throws GeneralSecurityException {
//        try {
//            SecretKeySpec key = new SecretKeySpec(apiV3Key.getBytes(StandardCharsets.UTF_8), "AES");
//            GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce.getBytes(StandardCharsets.UTF_8));
//
//            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
//            cipher.init(Cipher.DECRYPT_MODE, key, spec);
//            cipher.updateAAD(associatedData.getBytes(StandardCharsets.UTF_8)); // 设置附加认证数据
//
//            byte[] decodedCiphertext = Base64.getDecoder().decode(ciphertext);
//            byte[] decryptedBytes = cipher.doFinal(decodedCiphertext);
//
//            return new String(decryptedBytes, StandardCharsets.UTF_8);
//        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
//            throw new IllegalStateException("当前JDK环境不支持AEAD_AES_256_GCM", e);
//        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
//            throw new IllegalArgumentException("无效的密钥或GCM参数", e);
//        } catch (Exception e) {
//            // 包括 BadPaddingException 等解密失败的情况
//            throw new GeneralSecurityException("AES/GCM 解密失败", e);
//        }
//    }
//}