收藏
回答

java sdk, 应答的微信支付签名验证失败?

使用了证书管理器CertificatesManager,请求时使用其下载后的证书进行了敏感信息加密,但其SDK在验证响应时报错,这SDK还需要在哪设置啥呢?

Caused by: org.apache.http.HttpException: 应答的微信支付签名验证失败

at com.wechat.pay.contrib.apache.httpclient.SignatureExec.executeWithSignature(SignatureExec.java:91)

at com.wechat.pay.contrib.apache.httpclient.SignatureExec.execute(SignatureExec.java:61)

at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)

at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)

at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)

... 5 common frames omitted


再吐槽一下,这叫SDK?连demo都算不上啊

回答关注问题邀请回答
收藏

1 个回答

  • Pz
    Pz
    2022-10-07

    问题解决,单步调试发现响应的validator和请求使用的不一样,SDK中的withWechatPay这需传递平台密钥而非商户!


    以下贴出JAVA SDK需注意事项,没见过这么写SDK的,这些该声明的,不应该是SDK内部要做的事情吗?创意他们抄的很好,但代码,他们连抄都不会!!!!

    /*
    		敏感信息都需要用平台公钥进行加密,
    		RsaCryptoUtil.encryptOAEP("待加密内容", getWechatCertificate(payConfig))
    		
    		HTTP请求时,header需要带上平台证书信息
    		CloseableHttpClient client = getClient(payConfig);
    		
    		HttpPost httpost = new HttpPost(URL); //
    		httpost.addHeader("Content-Type", "application/json"); //这个SDK没有声明
    		httpost.addHeader("Wechatpay-Serial",getWechatCertificate(payConfig).getSerialNumber().toString(16));
    		
    		client.execute(httpost);
    		
    	 */
    
    
    	private WechatPayHttpClientBuilder builder = null;
    	private CloseableHttpClient getClient(PayConfig payConfig) {
    
    
    		if (builder == null) {
    			List<X509Certificate> certificates = new ArrayList<>();
    			certificates.add(getWechatCertificate(payConfig)); // 这里获取平台证书
    			builder = WechatPayHttpClientBuilder.create()
    					.withMerchant(payConfig.getMerchantId(),payConfig.getMerchantCertificateSerial(), getPrivateKey(payConfig.getMerchantCertificatePath())) //这里需设置商户私钥,私钥可从商户证书中可提取
    					.withWechatPay(certificates); //使用平台证书,这个会验证响应信息的签名
    
    
    		}
    
    
    		return builder.build();
    
    
    	}
    
    
    	// 证书管理器
    	private CertificatesManager certificatesManager = null;
    
    
    	// 此方法用于获取平台证书
    	private X509Certificate getWechatCertificate(PayConfig payConfig) { //PayConfig 中存放了商户ID,商户证书文件地址,商户证书编号,商户APIV3密钥,
    		if (certificatesManager == null) {
    			certificatesManager = CertificatesManager.getInstance();
    			try {
    				certificatesManager.putMerchant(payConfig.getMerchantId(),
    						new WechatPay2Credentials(payConfig.getMerchantId(),
    								new PrivateKeySigner(payConfig.getMerchantCertificateSerial(),
    										getPrivateKey(payConfig.getMerchantCertificatePath()))),
    						payConfig.getMerchantApiV3Key().getBytes(StandardCharsets.UTF_8)); // 注意这里的key,账户中心》API安全》设置APIv3密钥,这个字符串密钥
    			} catch (Exception e) {
    				logger.error("init wechat certificate manager error.", e);
    				throw PlatformError.code(BussErrorCode.PAY_KEY_ERROR);
    			}
    
    
    		}
    		try {
    			return CertificatesManager.getInstance().getVerifier(payConfig.getMerchantId()).getValidCertificate();
    		} catch (NotFoundException e) {
    			logger.error("get wechat certificate error.", e);
    			throw PlatformError.code(BussErrorCode.PAY_KEY_ERROR);
    		}
    
    
    	}
    
    
    	private PrivateKey privateKey = null;
    	private PrivateKey getPrivateKey(String merchantId, String keyFilePath) {
    		if (privateKey != null) {
    			return privateKey;
    		}
    		InputStream inputStream = null;
    		char[] keyPassword = merchantId.toCharArray();
    
    
    		try {
    			KeyStore keyStore = KeyStore.getInstance("PKCS12");
    			inputStream = new FileInputStream(new File(keyFilePath));
    			keyStore.load(inputStream, keyPassword);
    			String alias = keyStore.aliases().nextElement(); // 注意要这么获取alias
    			X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias);
    			
    			return (PrivateKey) keyStore.getKey(alias, keyPassword);
    		} catch (Exception e) {
    			logger.error("Analyse wechat certificate error.", e);
    			throw PlatformError.code(BussErrorCode.PAY_KEY_ERROR);
    
    
    		} finally {
    			if (inputStream != null) {
    				try {
    					inputStream.close();
    				} catch (IOException e) {
    				}
    			}
    
    
    		}
    	}
    
    2022-10-07
    有用
    回复
登录 后发表内容