AlipaySDKNet 是 .NET 平台下用于对接支付宝支付的官方 SDK。Alipay SDK for .NET 让您不用复杂编程即可访问支付宝开放平台开放的各项能力,SDK可以自动帮您满足能力调用过程中所需的证书校验、加签、验签、发送HTTP请求等非功能性要求。其 Nuget 链接如下:

https://www.nuget.org/packages/AlipaySDKNet.Standard

GitHub 开源地址为:

https://github.com/alipay/alipay-sdk-net-all

要在程序中集成支付宝支付其实并不困难,只要谨记 .NET 程序要用的私钥格式是 PKCS1 且不把参数搞混,问题应该都不大。

但是今天,却遇到了障碍:之前正常工作的代码在更换了账户配置(APPID、私钥等)之后竟然报错了。

Aop.Api.AopException: RSA签名遭遇异常,请检查私钥格式是否正确。Index was outside the bounds of the array.

根据报错时的堆栈信息,该错误来自于方法:

Aop.Api.Util.Asymmetric.RSAEncryptor.BuildRSAServiceProvider

本着先从自己找原因的原则从头到尾检查了配置参数:PKCS1 格式是对的、私钥是对的、公钥是对的甚至点鼠标的手势也是对的。

尝试了 Java 语言的 DEMO (其采用的是 PKCS8 格式),这套参数也是可以正常工作的那就说明密钥本身是没问题的。

无奈之下只能通过 GitHub 将代码克隆到本地并引入项目开始调试。找到报错位于 RSAEncryptor 的 BuildRSAServiceProvider 方法:

https://github.com/alipay/alipay-sdk-net-all/blob/98fc187884d628d4268504bc0b93eb9a1aae417a/AlipaySDKNet.Standard/Util/Asymmetric/RSAEncryptor.cs#L234

这个方法的作用是读取 PKCS1 格式私钥并构建 RSACryptoServiceProvider ,但转换过程略显过时。其实,.NET 在 netstandard-2.1 时已经提供了名为 ImportRSAPrivateKey 的方法用于导入密钥,这段代码可以直接被替换掉。

首先将 AlipaySDKNet.Standard 的目标框架修改为 netstandard2.1 ,接着使用以下代码替换掉 BuildRSAServiceProvider 方法的实现:

private static RSACryptoServiceProvider BuildRSAServiceProvider(byte[] privateKey)
{var rsa = new RSACryptoServiceProvider();rsa.ImportRSAPrivateKey(privateKey, out _);return rsa;
}

再次编译项目,已经可以正常下单使用了。

问题找到了,然后呢?

换一个密钥是最简单的方案。想要向阿里反馈这个问题,却发现该仓库并未开放 Issues 功能。我也想退而求其次,不要在项目中引入整个 SDK 的源代码(它太大了,有一万五千多个文件)而只对 SDK 打补丁。但我发现这很难做到:DefaultAopClient 的实现看上去很复杂,而且 BuildRSAServiceProvider 被定义为了一个私有的静态方法。

如何复现这个问题?

我当然不能把我现在使用的私钥共享出来,但我做了一些工作又生成了一个会报错的私钥(PKCS1 格式):

MIIEowIBAAKCAQEApkzj3sk+hpd2e0d8BUbDkuL6khflsJLzoQwGq25mm5fn2MDN3MPl/h0/XtWoM6OOIigvQFFj295UxN/I4oGrWL/oYA0g2MWlttLHPZ2ivhCSSizw9OJtAg8NgmkDM8dygAhyUQja2ZoACWrNrQa4DC10GXpRi/85ZGMEBcKZnUwlwYan31rVtgdULZ0l+W3yiWYtMaGKoT/BWQZ3bjUzCU/OxcuCK6Z/YUho65YxJa/zQdTmduxW7ghgGILqvoyh1PS1Zb+JeCJ3t6rxsoCDfKV7ldMUrWYKjMewvj6JritxgsmF/E80f12mMqDimLhJX8nTqQQ2kajEazkvZQNxaQIDAQABAoIBAACq2FNBjX2ux+vwun+u7AP/4y+I5wQRYubnjHNNqx2+u1B0XZ8gLiEZ7vIre1RRuLVMYfwpF3R/bOmpWD4IdS6S/pS8GMCl8mdMaz5FDq0ileO0UHc7HWLfupcmYrvndf8riYHnvjEXXB6tjgu+tiheWlPr2L3uFUXg29hGEqW98dSffYIWrdYOcFa1wWnR6w+FOEXqGcAppKKADosHCqA8S5M+tPcGbZ/PIJwcJEx+GsXsy1aoslB6hgAyJOmnY2w2o5V30I1QzhgiwCGAHK4pNABRtXwzGnSjfzdkrUb0irytvFrHj/RMuYHFaEJ8cSnc/c2sh87Zia5e6H6I+00CgYEA1d6oRlMCpfleUee0jl7KsGnqdoquipC7vNVjfPsSuGbXy9NRt/N4rSymfHsQA8zExmHfQjtk3kS64HXkUZRVrACNCLM6mgcEEshixRntaZJdA+RruPb45JBkhnjtmmQJ4BY06GTqtsflnaPJEv5wvReBlByThOcHI+fcOeUYfGcCgYEAxw9VAZfXxeVGT/+7skxxu1568OyrS7tysaMVy6Uufztd6hY3ZT+VV1QFxj8fku9miVFLCvhU4Z3HrahRmGNZ7XT0Cgm8ZhFhKKR7gQlAMAmLeSGgAUbjQ3BEKG5NXKqsFpAisoEV5/MoZ3eQuVGQ5JApbKZlhIVOX2Kq9gqmAa8CgYEAhfT9n3a1DPKBsnmX7SjQeekNc4xvwNjgzmk19H1qf1fjSIanA7obVxTFfuix4j9q7Ps2lMyQ5GtWRetxw+tOMfryW4WvafSFB6K9wsj3nI2RdzOmiWcgBEGwxU2PPYn1aYdfQkSbgzr3xmJlOmFmifnkLroraC4wmbvLg/PL/3cCgYA25PKDSvV1HIIkY5jGVbBzhF2Q/SNL8jhx5lCHZVkKOzvt5wyFvmAXwhMJlbTGV4DGU4XHU65Mva8oI6fEx3kwM7Vs4zxyRU6u35Uzg3KRDMDKucwfLgZUPax+HdT1vhdQ7ZSz90csPPEif2WIxYaYkWzrCoQqZHy1b0dILK2U/wKBgFAmZrWiB1mLp8hdLp49Fctf+KKH16t6CkhEzh0s+ElaRcuLQ/+m5nGSxBbPm7QeLxZBD12ugnj0czcRPfjWDNDTHghnXr+DNsVuQ8oUdrCQpwHgHpoeOzZaoX1RSSRceuZOiRaDJM/rf1CGi/LcXIE0YvlJF/eDCTlx6cOTFn7T

你也可以使用以下代码自己测试。该代码循环100次,并使用支付宝 SDK 提供的方法对密钥进行转换:

for (int i = 0; i < 100; i++)
{var rsa = RSA.Create();var keys = rsa.ExportRSAPrivateKey();try{BuildRSAServiceProvider(keys);}catch (Exception ex){Console.WriteLine(Convert.ToBase64String(keys));}
}

笔者的测试结果是:100 次生成大概会有 2-4 次遇到异常密钥。

如果你遇到了和笔者一样的问题,并且通读本文解决了你的问题。那么恭喜你,你大概就是天选之子,下班后去买彩吧,说不定能中。

后记

受制于笔者的知识浅薄,本文并没有找到 BuildRSAServiceProvider 不能正确加载私钥的根本原因,而是使用另一种方法规避了该问题。这让我更加坚信,即便是大厂的作品也不是完美无瑕。

简单总结一下:如果你遇到了本文所述的问题,那么就重置一下密钥吧。植发毕竟太贵了。

支付宝 .NET SDK 报错:RSA签名遭遇异常,请检查私钥格式是否正确。相关推荐

  1. 淘宝联盟 推广链接 API取链 转链报错 传入参数错误,请检查adzone_id是否属于appkey拥有者

    通过之前的取链文章,现在新增渠道时候报错 传入参数错误,请检查adzone_id是否属于appkey拥有者","request_id":"f7vemdro9du ...

  2. 打开 WORD 报错“无法创建工作文件, 请检查临时环境变量”

    打开WORD报错"无法创建工作文件,请检查临时环境变量"

  3. IDEA翻译插件Translation报错 更新 TKK 失败,请检查网络连接问题(已解决)

    用得好好的,今天突然就翻译不了,提示这玩意,解决思路如下: 现在修改本地文件也不能用了,好像是因为谷歌关闭了国内的接口,可以使用方法三(本人再用);       方法三就是不能朗读,只能翻译文本,日常 ...

  4. ytb网站报错 “您没有联网,请检查网络连接”

    问题原因&解决办法:计算机时间有问题,在设置中"同步"时间.并且关闭路由器的Ipv6以绝后患 xxxxxxx.com/core/proxy/vmess/encoding: ...

  5. 安装PhotoShop报错 无法写入注册表值请检查权限(错误代码160)

    第一步判断电脑中是否有2345的软件,有的话卸载掉即可.这玩意儿不知道为什么阻止安装 PhotoShop 若第一步没有用,Win+R 输入Regedit打开系统注册表 展开HKEY_LOCAL_MAC ...

  6. 已解决,错误码2,ytb网站报错 “您没有联网,请检查网络连接”

    如果是时间问题,建议先看这篇 https://blog.csdn.net/weixin_42375356/article/details/113816276 2021/04/17 17:47:42 t ...

  7. php 使用支付宝SDK报错解决

    php 使用支付宝SDK报错解决 php7.2 报错The each() function is deprecated. This message will be suppressed on furt ...

  8. TP3.2如何加载第三方类库?加载腾讯短信sdk 报错。

    TP3.2如何加载第三方类库?加载腾讯短信sdk 报错 主要在于引入 Vendor('qcloudsms.index'); index.php后还需要use引入命名空间,不然就会报类未定义的错误. & ...

  9. yarn create @umijs/umi-app或者yarn create umi myapp 报错:文件名、目录名或卷标语法不正确。

    1. Problem Description 在学习ant-design,使用 @umijs/umi-app 为模板,创建一个项目: 和ant-design-pro的时候,使用umi myapp 创建 ...

最新文章

  1. jQuery学习---------认识事件处理
  2. 什么样的对象会进入老年代
  3. Linux之虚拟机里的REHL7的IP
  4. clr enabled Server Configuration Option
  5. labview事件结构
  6. linux修改栈指针x86,为什么x86-64 Linux系统调用会修改RCX,这个值意味着什么?
  7. fgetc与EOF的错综复杂关系
  8. 推荐 一个PDF转Word内容不匹配、乱码的解决方法
  9. 软件测试:三角形问题
  10. Unity中使用Google.Protobuf3,获取dll文件
  11. 第60天:攻防世界Mobile两道题
  12. 0044-【宏基因组】-16S分析qiime1极简教程
  13. 各种颜色:RGB值标准
  14. (三)AsyncTask
  15. 如何删除WORD空白页
  16. netty对http协议解析原理解析
  17. 微服务架构,这一篇就够了!
  18. Web常用的服务器软件整理(Win+Linux)
  19. JS实现简单的网页新闻无缝滚动
  20. RTX 报错(应用SDK服务器:超出支持的最大应用数目)解决办法

热门文章

  1. Html中如何让超链接a、图片img居中
  2. 关于epoll,select,poll的理解
  3. Web前端笔试面试题汇总(转自github)
  4. 转:iOS-CoreLocation:无论你在哪里,我都要找到你!
  5. Electron - 创建跨平台的桌面客户的应用程序
  6. 我到底要选择一种什么样的生活方式,度过这一辈子呢:人生自由与职业发展方向(下)...
  7. SQL 中的unicode字符
  8. What's blocking my lock? 转载
  9. 6、struts.properties配置详解
  10. c语言编手机蓝牙软件的代码,51单片机C语言的简易蓝牙锁代码