java微信退款解密,微信退款-异步通知 报文解密

拿到报文 对req_info 用商户秘钥进行解密

package com.ly.upg.message.util;

import com.alibaba.fastjson.JSONObject;

import com.snake.bsys.common.log.Log;

import com.tencent.common.MD5;

import com.tencent.common.XMLParser;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.BadPaddingException;

import javax.crypto.Cipher;

import javax.crypto.IllegalBlockSizeException;

import javax.crypto.NoSuchPaddingException;

import javax.crypto.spec.SecretKeySpec;

import java.security.InvalidKeyException;

import java.security.NoSuchAlgorithmException;

import java.security.NoSuchProviderException;

import java.security.Security;

import java.util.Base64;

import java.util.HashMap;

import java.util.Map;

/**

* @Title:

* @Description:微信退款报文解密

* @Created by yangjie on 2020/1/4/15:18.

*/

public class WxDecryptUtil {

public static Map excute(String keyStr,String orgStr) throws BadPaddingException, IllegalBlockSizeException {

//MD5.MD5Encode(secretKey).toLowerCase().getBytes()

SecretKeySpec key = new SecretKeySpec((MD5.MD5Encode(keyStr).toLowerCase().getBytes()), "AES");

Security.addProvider(new BouncyCastleProvider());

Cipher cipher = null;

try {

cipher = Cipher.getInstance("AES/ECB/PKCS7Padding", "BC");

} catch (NoSuchAlgorithmException e) {

e.printStackTrace();

} catch (NoSuchProviderException e) {

e.printStackTrace();

} catch (NoSuchPaddingException e) {

e.printStackTrace();

}

try {

cipher.init(Cipher.DECRYPT_MODE, key);

} catch (InvalidKeyException e) {

e.printStackTrace();

}

Base64.Decoder decoder = Base64.getDecoder();

String reqInfo = orgStr.replaceAll(" ","+");

byte[] decryptContent = cipher.doFinal(decode(reqInfo));

try {

Map map = new HashMap();

map = XMLParser.getMapFromXML(new String(decryptContent, "utf-8"));

Log.logger.info("微信解密后的报文-->"+ JSONObject.toJSONString(map));

return map;

} catch (Exception e) {

e.printStackTrace();

}

return null;

}

public static byte[] decode(String encodedText){

final Base64.Decoder decoder = Base64.getDecoder();

return decoder.decode(encodedText);

}

public static void main(String[] args) {

try {

// req_info

String org = "Nr2R4wa3OQpKFFV3EmMB463MPGliaPI78OKgLy61tSwbDwE2SCPgUYG9yls54PSOMmgPdCUia2BYKAnzFdNmQdyWDNIN4XO9mHNcFw/ubwVyeBqzs1CVvqPZEhV4hEfgGrK81x58YsvewULHS0JAkZgtGXDFgduaaV179Wny7YiogFk0i/hromZgGyG1+emNJxJhzo7KkEqSSztRMTOJp+28RyV4iEIWD1WvKJkiKx4/yNOXVsRTaKXEeKnlMj5v01lVdsxUa1HziW5PT6l7wp0bfOVU3mc2+aYf7dgqT9NWEZ56bU92+27l/GKa3fFTDvjFNNqDcGP66AmfAToL8D09peXCj8t2J9Af7+5mngRqGVzNM/FBOnK6th3nmDZFp9Acoy4wxskDloLUB4KBZjtnZYyEAq9Bex7AZMwsW10uLy8TXLwUh9j0WGXORKytne2gbnHEHfbGp/6xmp1EOZKHRJPAW198cYrzEy8WqTVjv3fqWqnw2rrcDwFp57PLk4e1QPec4rRwloP71p4oS8q6Hj3ZLYENRI74iofhUhZRryPtcQNeaXDBWC0Q2VWW/va6BpaKA1f0eOG5ITcoaoqaECFTz10B9vyX5MbVIjjSRmiQV2bY3d4c2y794Bh3VxZkLrEJ3pjbb9Jc8abwfDD9gjxlGW/gj9AbnKpjuoeGsj/RJqzspmNmwQxnxkQ7MEejbX0xgc0y4mq6EuFxJcqkEcFxNwrjheIqTNkGbIk8vjeimbKIh820GKmKmF4HNYV0z6h3dCF/7Jp9HhnxpvQdIwDpUzeQe8QXI0+I3yO36hdXeo3qH/bUtbQO/nN20HwbDvVanMIvA5Gp1RcRngY2uFx38CReqmIhbn5j4L+SwtmQ6B0LXqlAb/HQPeXd891Bq6vf8GwdQGygZOIETzddfblhCPBvNe0a7oaWY7ygXNM+HQw/9T1tEfesrBy2JL4BPhAjqlTUDZfldLd3Mf0MhMJNaEWXI+iUFRsXbRlIHuURglFzrZWvl/UzPGZk/nhpp5p4yX/HF9z0iObanrxLIJRAdPB1qAReLoC7BztScICQ8vF5euSk3cczPeU8";

// 商户秘钥

String key = "HqPzKWBaZyhvClKXiqUO2uR5kzg84Pyb";

Map test = excute(key,org);

} catch (BadPaddingException e) {

e.printStackTrace();

} catch (IllegalBlockSizeException e) {

e.printStackTrace();

}

}

}

package com.ly.upg.message.util;

import com.alibaba.fastjson.JSONObject;

import com.snake.bsys.common.log.Log;

import com.tencent.common.MD5;

import com.tencent.common.XMLParser;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import org.xml.sax.SAXException;

import javax.crypto.Cipher;

import javax.crypto.spec.SecretKeySpec;

import javax.xml.parsers.ParserConfigurationException;

import java.io.IOException;

import java.security.Security;

import java.util.Base64;

import java.util.HashMap;

import java.util.Map;

/**

* @Title:

* @Description:

* @Created by yangjie on 2020/1/3/18:46.

*/

public class CipherTextUtil {

/**

* 密钥算法

*/

private static final String ALGORITHM = "AES";

/**

* 加解密算法/工作模式/填充方式

*/

private static final String ALGORITHM_MODE_PADDING = "AES/ECB/PKCS7Padding";

static {

try {

Security.addProvider(new BouncyCastleProvider());

} catch (Exception e) {

e.printStackTrace();

}

}

/**

* AES解密

*/

public static String decryptData(byte[] b,SecretKeySpec key) throws Exception {

Cipher cipher = Cipher.getInstance(ALGORITHM_MODE_PADDING);

cipher.init(Cipher.DECRYPT_MODE, key);

return new String(cipher.doFinal(b));

}

public static Map decrypt(String secretKey, String orgStr) throws IOException, SAXException, ParserConfigurationException {

SecretKeySpec key = new SecretKeySpec(MD5.MD5Encode(secretKey).toLowerCase().getBytes(), ALGORITHM);

Log.logger.info("微信退款解密原始字符串-->"+orgStr);

Log.logger.info("微信退款解密key-->"+secretKey);

byte[] b = new byte[0];

try {

b = Base64Util.decode(orgStr.replaceAll(" ","+"));

if(b == null|| b.length == 0){

Log.logger.error("微信解密原始字符串-解码失败decode.");

return null;

}

}catch (Exception e){

Log.logger.error("微信解密原始字符串-解码异常decode.");

}

String B = null;

try {

Log.logger.info("微信退款报文解密AES解密开始:解码b="+JSONObject.toJSONString(b)+",秘钥key="+key.toString());

Log.logger.info("微信退款报文解密AES解密开始:解码b="+b.length);

B = decryptData(b,key);

} catch (Exception e) {

Log.logger.error("微信退款报文解密AES解密失败"+e.getMessage());

e.printStackTrace();

return null;

}

Map map = new HashMap();

map = XMLParser.getMapFromXML(B);

Log.logger.info("微信解密后的报文-->"+JSONObject.toJSONString(map));

return map;

}

public static byte[] decode(String encodedText){

final Base64.Decoder decoder = Base64.getDecoder();

return decoder.decode(encodedText);

}

public static void main(String[] args) throws Exception {

String A = "Nr2R4wa3OQpKFFV3EmMB463MPGliaPI78OKgLy61tSwbDwE2SCPgUYG9yls54PSOMmgPdCUia2BYKAnzFdNmQdyWDNIN4XO9mHNcFw/ubwVyeBqzs1CVvqPZEhV4hEfgGrK81x58YsvewULHS0JAkZgtGXDFgduaaV179Wny7YiogFk0i/hromZgGyG1+emNJxJhzo7KkEqSSztRMTOJp+28RyV4iEIWD1WvKJkiKx4/yNOXVsRTaKXEeKnlMj5v01lVdsxUa1HziW5PT6l7wp0bfOVU3mc2+aYf7dgqT9NWEZ56bU92+27l/GKa3fFTDvjFNNqDcGP66AmfAToL8D09peXCj8t2J9Af7+5mngRqGVzNM/FBOnK6th3nmDZFp9Acoy4wxskDloLUB4KBZjtnZYyEAq9Bex7AZMwsW10uLy8TXLwUh9j0WGXORKytne2gbnHEHfbGp/6xmp1EOZKHRJPAW198cYrzEy8WqTVjv3fqWqnw2rrcDwFp57PLk4e1QPec4rRwloP71p4oS8q6Hj3ZLYENRI74iofhUhZRryPtcQNeaXDBWC0Q2VWW/va6BpaKA1f0eOG5ITcoaoqaECFTz10B9vyX5MbVIjjSRmiQV2bY3d4c2y794Bh3VxZkLrEJ3pjbb9Jc8abwfDD9gjxlGW/gj9AbnKpjuoeGsj/RJqzspmNmwQxnxkQ7MEejbX0xgc0y4mq6EuFxJcqkEcFxNwrjheIqTNkGbIk8vjeimbKIh820GKmKmF4HNYV0z6h3dCF/7Jp9HhnxpvQdIwDpUzeQe8QXI0+I3yO36hdXeo3qH/bUtbQO/nN20HwbDvVanMIvA5Gp1RcRngY2uFx38CReqmIhbn5j4L+SwtmQ6B0LXqlAb/HQPeXd891Bq6vf8GwdQGygZOIETzddfblhCPBvNe0a7oaWY7ygXNM+HQw/9T1tEfesrBy2JL4BPhAjqlTUDZfldLd3Mf0MhMJNaEWXI+iUFRsXbRlIHuURglFzrZWvl/UzPGZk/nhpp5p4yX/HF9z0iObanrxLIJRAdPB1qAReLoC7BztScICQ8vF5euSk3cczPeU8";

byte[] b = Base64Util.decode(A.replaceAll(" ","+"));

Map map = decrypt("HqPzKWBaZyhvClKXiqUO2uR5kzg84Pyb", A);

System.out.println(JSONObject.toJSONString(map));

}

}

很诡异的问题是在服务器 总是报 pad block corrupted 错误 至今未解决 难搞哦

来源:oschina

链接:https://my.oschina.net/u/3690153/blog/3154109

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,针对你的问题,我可以提供以下解密微信退款通知req_info的Java代码示例: ```java import java.io.ByteArrayInputStream; import java.io.InputStream; import java.security.Key; import java.security.KeyFactory; import java.security.PublicKey; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import javax.crypto.Cipher; public class WechatRefundNotify { private static final String PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\n" + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDc8j2WJbF/1kxva8sUcU9e5n9v\n" + "GzOzX4FfB1z8VfJmP9AKJj1ZyDpMgE1l8zZxWzO0J8m1cUH3Rj5HbH+VjwVJcWj0\n" + "g9yYb2DvZUnK0vSjxXW0nHv+9UJrGzqHv+5j1EF8Av3d0mPv5dZ1N2r7sRwZCj3s\n" + "eLmZs5Ql5Z+8n0qazQIDAQAB\n" + "-----END PUBLIC KEY-----"; public static void main(String[] args) throws Exception { String encryptedReqInfo = "Jzjy4tPnE80DZzJGV8O5JtGJ2Wgc9LjNv+KMrDR/RNjXuytIg2+Gj0btS/3kC9pUgZG0sGkkSHZr6W0X9Ql4r4Bx0+6LX2aC4HfjZjNjQD9pEnYz570O5V7LjVnX3W8LLKz4lwQhZoDUEjGgkKvQzj5MmSmHjV7F1sLqWlXzTQVbVJpKl0tDwvJuZjNYWcV9+HlJnC3GphH5q2q+P6yV6lV3pcz6j0v8Z+JyK2+D8w3yUZ9K9t0pB27+qI3W6Qn6kJnq+J8Uz6F7v4Yn8X9aZ8NQgD7SWu0PQOg9nH1mz0JW5Ur0L+J2nXK4I+oMk0hO5LX5Nx/4f+54bCzVcBh1VlJ2Z9+6Fq0g=="; String mchKey = "your_mch_key"; String reqInfo = decryptReqInfo(encryptedReqInfo, mchKey); System.out.println(reqInfo); } public static String decryptReqInfo(String encryptedReqInfo, String mchKey) throws Exception { byte[] encryptedReqInfoBytes = Base64.getDecoder().decode(encryptedReqInfo); // 解密AES密钥 byte[] mchKeyBytes = Base64.getDecoder().decode(mchKey); Key aesKey = new javax.crypto.spec.SecretKeySpec(mchKeyBytes, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding"); cipher.init(Cipher.DECRYPT_MODE, aesKey); byte[] decryptedAesKeyBytes = cipher.doFinal(encryptedReqInfoBytes, 0, 32); // RSA解密req_info byte[] encryptedReqInfoNoAesKeyBytes = new byte[encryptedReqInfoBytes.length - 32]; System.arraycopy(encryptedReqInfoBytes, 32, encryptedReqInfoNoAesKeyBytes, 0, encryptedReqInfoNoAesKeyBytes.length); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); InputStream inputStream = new ByteArrayInputStream(PUBLIC_KEY.getBytes()); byte[] publicKeyBytes = new byte[inputStream.available()]; inputStream.read(publicKeyBytes); X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes); PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); cipher.init(Cipher.DECRYPT_MODE, publicKey); byte[] reqInfoBytes = cipher.doFinal(encryptedReqInfoNoAesKeyBytes); return new String(reqInfoBytes); } } ``` 其中,`encryptedReqInfo` 是微信退款通知接口返回的 `req_info` 参数的值,`mchKey` 是商户密钥,`PUBLIC_KEY` 是微信支付平台的公钥,需要在微信商户平台获取。 需要注意的是,上述代码中使用了 `javax.crypto` 和 `java.security` 包,需要在项目中引入相关的依赖。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值