fix: 查询并下载转账电子回单API接口,下载文件接口签名失败

微信协议不统一造成的不兼容,1.0.8发布会修正这个问题。

Closes #18
This commit is contained in:
felord.cn
2021-03-11 14:39:56 +08:00
committed by felord.cn
parent 4f71f419a7
commit ab13d90b9b
3 changed files with 25 additions and 16 deletions

View File

@@ -120,6 +120,7 @@ public class SignatureProvider {
/** /**
* 我方请求前用 SHA256withRSA 加签使用API证书. * 我方请求前用 SHA256withRSA 加签使用API证书.
* *
* @param newLine the new line
* @param tenantId the properties key * @param tenantId the properties key
* @param method the method * @param method the method
* @param canonicalUrl the canonical url * @param canonicalUrl the canonical url
@@ -127,7 +128,7 @@ public class SignatureProvider {
* @return the string * @return the string
*/ */
@SneakyThrows @SneakyThrows
public String requestSign(String tenantId, String method, String canonicalUrl, String body) { public String requestSign(boolean newLine,String tenantId, String method, String canonicalUrl, String body) {
long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")); long timestamp = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
String nonceStr = nonceStrGenerator.generateId() String nonceStr = nonceStrGenerator.generateId()
@@ -135,7 +136,7 @@ public class SignatureProvider {
.replaceAll("-", ""); .replaceAll("-", "");
WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId); WechatMetaBean wechatMetaBean = wechatMetaContainer.getWechatMeta(tenantId);
PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate(); PrivateKey privateKey = wechatMetaBean.getKeyPair().getPrivate();
String encode = this.doRequestSign(privateKey, method, canonicalUrl, String.valueOf(timestamp), nonceStr, body); String encode = this.doRequestSign(newLine,privateKey, method, canonicalUrl, String.valueOf(timestamp), nonceStr, body);
// 序列号 // 序列号
String serialNo = wechatMetaBean.getSerialNumber(); String serialNo = wechatMetaBean.getSerialNumber();
// 生成token // 生成token
@@ -149,16 +150,17 @@ public class SignatureProvider {
/** /**
* Do request sign. * Do request sign.
* *
* @param newLine the has suffix
* @param privateKey the private key * @param privateKey the private key
* @param orderedComponents the orderedComponents * @param orderedComponents the orderedComponents
* @return the string * @return the string
* @since 1.0.4.RELEASE * @since 1.0.4.RELEASE
*/ */
@SneakyThrows @SneakyThrows
public String doRequestSign(PrivateKey privateKey, String... orderedComponents) { public String doRequestSign(boolean newLine,PrivateKey privateKey, String... orderedComponents) {
Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER); Signature signer = Signature.getInstance("SHA256withRSA", BC_PROVIDER);
signer.initSign(privateKey); signer.initSign(privateKey);
final String signatureStr = createSign(orderedComponents); final String signatureStr = createSign(newLine,orderedComponents);
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8)); signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
return Base64Utils.encodeToString(signer.sign()); return Base64Utils.encodeToString(signer.sign());
} }
@@ -178,7 +180,7 @@ public class SignatureProvider {
} }
Certificate certificate = CERTIFICATE_MAP.get(wechatpaySerial); Certificate certificate = CERTIFICATE_MAP.get(wechatpaySerial);
final String signatureStr = createSign(params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody()); final String signatureStr = createSign(true,params.getWechatpayTimestamp(), params.getWechatpayNonce(), params.getBody());
Signature signer = Signature.getInstance("SHA256withRSA"); Signature signer = Signature.getInstance("SHA256withRSA");
signer.initVerify(certificate); signer.initVerify(certificate);
signer.update(signatureStr.getBytes(StandardCharsets.UTF_8)); signer.update(signatureStr.getBytes(StandardCharsets.UTF_8));
@@ -206,7 +208,7 @@ public class SignatureProvider {
} }
// 签名 // 签名
HttpMethod httpMethod = WechatPayV3Type.CERT.method(); HttpMethod httpMethod = WechatPayV3Type.CERT.method();
String authorization = requestSign(tenantId, httpMethod.name(), canonicalUrl, ""); String authorization = requestSign(true,tenantId, httpMethod.name(), canonicalUrl, "");
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
@@ -278,7 +280,7 @@ public class SignatureProvider {
/** /**
* 对请求敏感字段进行加密 * 对请求敏感字段进行加密
* *
* @param message the message * @param message the message
* @param certificate the certificate * @param certificate the certificate
* @return encrypt message * @return encrypt message
* @since 1.0.6.RELEASE * @since 1.0.6.RELEASE
@@ -297,6 +299,11 @@ public class SignatureProvider {
} }
} }
/**
* Get certificate x 509 wechat certificate info.
*
* @return the x 509 wechat certificate info
*/
public X509WechatCertificateInfo getCertificate(){ public X509WechatCertificateInfo getCertificate(){
for (String serial : CERTIFICATE_MAP.keySet()) { for (String serial : CERTIFICATE_MAP.keySet()) {
X509Certificate x509Cert = (X509Certificate) CERTIFICATE_MAP.get(serial); X509Certificate x509Cert = (X509Certificate) CERTIFICATE_MAP.get(serial);
@@ -341,9 +348,11 @@ public class SignatureProvider {
* @param components the components * @param components the components
* @return string string * @return string string
*/ */
private static String createSign(String... components) { private static String createSign(boolean newLine,String... components) {
String suffix = newLine? "\n":"";
return Arrays.stream(components) return Arrays.stream(components)
.collect(Collectors.joining("\n", "", "\n")); .collect(Collectors.joining("\n", "", suffix));
} }
} }

View File

@@ -87,7 +87,7 @@ public class WechatDirectPayApi extends AbstractApi {
.toString() .toString()
.replaceAll("-", ""); .replaceAll("-", "");
String prepayId = body.get("prepay_id").asText(); String prepayId = body.get("prepay_id").asText();
String paySign = signatureProvider.doRequestSign(privateKey, appId, timestamp, nonceStr, prepayId); String paySign = signatureProvider.doRequestSign(true,privateKey, appId, timestamp, nonceStr, prepayId);
String mchId = wechatMetaBean.getV3().getMchId(); String mchId = wechatMetaBean.getV3().getMchId();
body.put("appid", appId); body.put("appid", appId);
@@ -136,7 +136,7 @@ public class WechatDirectPayApi extends AbstractApi {
.toString() .toString()
.replaceAll("-", ""); .replaceAll("-", "");
String packageStr = "prepay_id=" + body.get("prepay_id").asText(); String packageStr = "prepay_id=" + body.get("prepay_id").asText();
String paySign = signatureProvider.doRequestSign(privateKey, appId, timestamp, nonceStr, packageStr); String paySign = signatureProvider.doRequestSign(true,privateKey, appId, timestamp, nonceStr, packageStr);
body.put("appId", appId); body.put("appId", appId);
body.put("timeStamp", timestamp); body.put("timeStamp", timestamp);

View File

@@ -164,7 +164,7 @@ public class WechatPayClient {
public void request() { public void request() {
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model); RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer); WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
this.doExecute(this.header(wechatRequestEntity)); this.doExecute(this.header(true,wechatRequestEntity));
} }
@@ -176,7 +176,7 @@ public class WechatPayClient {
public String download() { public String download() {
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model); RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer); WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
return this.doDownload(this.header(wechatRequestEntity)); return this.doDownload(this.header(true,wechatRequestEntity));
} }
/** /**
@@ -188,7 +188,7 @@ public class WechatPayClient {
public ResponseEntity<Resource> resource() { public ResponseEntity<Resource> resource() {
RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model); RequestEntity<?> requestEntity = this.requestEntityBiFunction.apply(this.wechatPayV3Type, this.model);
WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer); WechatRequestEntity<?> wechatRequestEntity = WechatRequestEntity.of(requestEntity, this.responseBodyConsumer);
return this.doResource(this.header(wechatRequestEntity)); return this.doResource(this.header(false,wechatRequestEntity));
} }
@@ -199,7 +199,7 @@ public class WechatPayClient {
* @param requestEntity the request entity * @param requestEntity the request entity
* @return the wechat request entity * @return the wechat request entity
*/ */
private <T> WechatRequestEntity<T> header(WechatRequestEntity<T> requestEntity) { private <T> WechatRequestEntity<T> header(boolean newLine,WechatRequestEntity<T> requestEntity) {
UriComponents uri = UriComponentsBuilder.fromUri(requestEntity.getUrl()).build(); UriComponents uri = UriComponentsBuilder.fromUri(requestEntity.getUrl()).build();
String canonicalUrl = uri.getPath(); String canonicalUrl = uri.getPath();
@@ -220,7 +220,7 @@ public class WechatPayClient {
} }
String tenantId = Objects.requireNonNull(headers.get("Pay-TenantId")).get(0); String tenantId = Objects.requireNonNull(headers.get("Pay-TenantId")).get(0);
String authorization = signatureProvider.requestSign(tenantId, httpMethod.name(), canonicalUrl, body); String authorization = signatureProvider.requestSign(newLine,tenantId, httpMethod.name(), canonicalUrl, body);
HttpHeaders httpHeaders = new HttpHeaders(); HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.addAll(headers); httpHeaders.addAll(headers);