Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Init NewClient Error #135

Closed
lucky0604 opened this issue Nov 1, 2022 · 10 comments
Closed

Init NewClient Error #135

lucky0604 opened this issue Nov 1, 2022 · 10 comments
Assignees

Comments

@lucky0604
Copy link

bug
按照示例代码进行测试,商户号,秘钥等都是按照文档操作通过服务商后台进行配置,证书为下载好通过本地读取文件方式进行加载压缩包中提供好的apiclient_key.pem文件

opts := []core.ClientOption{
		option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
	}

报错:decrypt downloaded certificate failed: cipher: message authentication failed.

  • Go 版本:
    1.17.3
  • wechatpay-go 版本:
    wechatpay-apiv3/wechatpay-go@v0.2.16
@xy-peng
Copy link
Contributor

xy-peng commented Nov 1, 2022

看提示是下载微信支付平台证书时失败了。

mchAPIv3Key 是对的吗?用这个密钥能成功下载证书吗?

你试试用 证书下载工具 下载证书。

@lucky0604
Copy link
Author

lucky0604 commented Nov 1, 2022

使用这个工具通过jar包下载,返回ERROR com.wechat.pay.contrib.apache.httpclient.auth.CertificatesVerifier - 找不到证书序列号对应的证书,序列号:41*********D08184497****************
目前我的证书文件夹是通过https://kf.qq.com/faq/161222NneAJf161222U7fARv.html
这个文档按步骤生成,生成后下载下来的文件夹中有一个apiclient_key.pem,apiclient_cert.pem,apiclient_cert.p12和一个使用说明,按照说明文档中的描述这个key.pem应该是生成好可直接使用的,序列号是通过openssl x509 -in apiclient_cert.pem -noout -serial得到,但这个序列号和上面报错的序列号不同
在文档中提供的postman pre-request script文件中使用我现在的商户号和mchAPIv3Key以及apiclient_key.pem中的密钥发起请求可以得到返回,内容包含ciphertext和一个serial_no,并且这个serial_no和上面通过Java下载找不到序列号对应证书的序列号是一样的

@xy-peng
Copy link
Contributor

xy-peng commented Nov 2, 2022

商户 API 证书,是用来证实商户身份的。证书中包含商户号、证书序列号、证书有效期等信息,由证书授权机构(Certificate Authority ,简称 CA)签发,以防证书被伪造或篡改。如何获取请见 商户 API 证书
商户 API 私钥。商户申请商户 API 证书时,会生成商户私钥,并保存在本地证书文件夹的文件 apiclient_key.pem 中。

微信支付平台证书。微信支付平台证书是指由微信支付负责申请的,包含微信支付平台标识、公钥信息的证书。商户使用微信支付平台证书中的公钥验证应答签名。获取微信支付平台证书需通过 获取平台证书列表 接口下载。

有两个证书,看看是不是弄混了。

@lucky0604
Copy link
Author

lucky0604 commented Nov 4, 2022

今天重新试了一下
步骤是这样

  • 根据https://kf.qq.com/faq/161222NneAJf161222U7fARv.html这个步骤重新生成证书压缩包,里面包含4个文件,分别是
    • 证书使用说明.txt
    • apiclient_cert.pem
    • apiclient_key.pem
    • apiclient_cert.p12
  • 使用openssl工具,解析apiclient_cert.pem,得到证书序列号
  • 根据jsapi的示例中使用CloseOrder进行测试请求
    • mchID不变
    • mchAPIv3Key不变
    • mchCertificateSerialNumber是上一步中解析出来的,在商户后台查看证书序列号也是对的
    • utils.LoadPrivateKeyWithPath(“/path/to/apiclient_key.pem")
      以上是完整的配置步骤,根据以上的配置步骤,仍然报错decrypt downloaded certificate failed: cipher: message authentication failed

补充一下:
https://developers.weixin.qq.com/community/develop/article/doc/000ce8d3ee8b70d868ed6185b5b013

根据这个文档里的验签说明,使用postman pre-request script进行微信支付平台证书的下载请求是正确的,那么应该说明我的证书,商户ID,证书序列号是正确的

代码片段

var (
		mchID                      string = "11111111"                               // 商户号
		mchCertificateSerialNumber string = "11111111111111" // 商户证书序列号
		mchAPIv3Key                string = "okadfdsfsdfsf**********"         // 商户APIv3密钥
	)

	// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
	mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/apiclient_key.pem")

	if err != nil {
		log.Print("load merchant private key error")
	}
	fmt.Println(mchPrivateKey)
	fmt.Println(mchID)
	fmt.Println(mchCertificateSerialNumber)
	fmt.Println(mchAPIv3Key)
	ctx := context.Background()
	// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
	opts := []core.ClientOption{
		option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
	}
	fmt.Println(opts)
	client, err := core.NewClient(ctx, opts...)
	if err != nil {
		log.Printf("new wechat pay client err:%s", err)
	}

	svc := jsapi.JsapiApiService{Client: client}

报错是在opts := []core.ClientOption{}
也就是说WithWechatPayAutoAuthCipher()方法应该有问题

@xy-peng
Copy link
Contributor

xy-peng commented Nov 6, 2022

根据这个文档里的验签说明,使用postman pre-request script进行微信支付平台证书的下载请求是正确的,那么应该说明我的证书,商户ID,证书序列号是正确的

你检查下你的 APIv3Key 是否正确?

从微信支付平台证书下载接口获取到的证书使用了 APIv3Key 做了 AES_GCM 加密。如果 APIv3Key 不正确,会导致 WithWechatPayAutoAuthCipher 失败。

@lucky0604
Copy link
Author

lucky0604 commented Nov 6, 2022

APIV3Key是正确的,在证书下,有v2和v3,这个检查了一下,就是v3key,应该不会出错
现在应该不是通过微信支付证书下载接口获取到的证书解密问题
看上面代码的逻辑,是初始化之前的core.ClientOption初始化问题,还没到调用jsapi去发起请求

@xy-peng
Copy link
Contributor

xy-peng commented Nov 7, 2022

初始化的过程,会使用 APIv3Key 解密微信支付平台证书。

在文档中提供的postman pre-request script文件中使用我现在的商户号和mchAPIv3Key以及apiclient_key.pem中的密钥发起请求可以得到返回,内容包含ciphertext和一个serial_no,并且这个serial_no和上面通过Java下载找不到序列号对应证书的序列号是一样的

你可以试试能否解密微信支付平台证书下载得到的 ciphertext。可以找一些 AES-GCM 在线解密的服务,也可以用 utils/aes 试试。

@lucky0604
Copy link
Author

使用utils/aes里的方法解密返回空,错误信息cipher: message authentication failed
这样应该说明是Apiv3Key错误吧?
但是我是在
image
这里配置的,应该不会出错啊

@xy-peng
Copy link
Contributor

xy-peng commented Nov 7, 2022

是这里配置。如果不影响现网业务,可以试着重置一次试试。

@lucky0604
Copy link
Author

可以了,重置一下ApiV3Key即可。
这里贴下总结,方便以后有相同情况的朋友进行错误排查:
若确定mchID, serialNumber, mchPrivateKey都正确的情况下,返回解密失败,同时有之前就存在的apiV3Key,可以尝试重置apiV3Key,虽然不知道具体是什么原理。

@xy-peng xy-peng closed this as completed Nov 7, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants